【问题标题】:how to call mainActivity method in customeAdapter如何在自定义适配器中调用 mainActivity 方法
【发布时间】:2018-08-22 15:40:29
【问题描述】:

我在 kotlin 中使用 recyclerview,我是 kotlin 的新手。我在其中使用了button.setOnClickListner 方法。我想调用我的mainActivity 中的一个方法。我该怎么做呢

我想调用mainActivity中的以下方法

fun sendOrder() {

        Log.e("TAG", "SendOrder: "  )

    }

我的适配器在下面

class CustomAdapterJob(val jobList: ArrayList<JobData>): RecyclerView.Adapter<CustomAdapterJob.ViewHolder>(){
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
    val jobData :JobData = jobList[position]
    holder?.textViewId?.text = jobData.id
    holder?.textViewArea?.text = jobData.area
    holder?.textViewCarType?.text = jobData.carType
    holder?.textViewCarName?.text = jobData.carName
    holder?. textViewDutyHours?.text = jobData.dutyHours
    holder?.textViewWeeklyOff?.text = jobData.weeklyOff
    holder?.textViewDriverAge?.text = jobData.driverAge
    holder?.textViewDriverExperience?.text = jobData.drivingExperience
    holder?.textViewOutstationDays?.text = jobData.outstationDays
    holder?.textViewDutyDetails?.text = jobData.dutyDetails
    holder?.button?.text =jobData.submit
    if(jobData.submit == "true"){
        holder?.button?.setVisibility(View.GONE);
    }

    holder?.button?.setOnClickListener( View.OnClickListener (){
        Log.d("TAG", "job list position : ${jobList[position].id}")
        var id = jobList[position].id
        val p = Pattern.compile("-?\\d+")
        val m = p.matcher(id)
        while (m.find()) {
            System.out.println(m.group())
            sendOrder()
        }
    });

    //To change body of created functions use File | Settings | File Templates.
}

override fun getItemCount(): Int {
     return jobList.size//To change body of created functions use File | Settings | File Templates.
}

override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
    val v=LayoutInflater.from(parent?.context).inflate(R.layout.job_card,parent,false)
    return ViewHolder(v)
    //To change body of created functions use File | Settings | File Templates.
}

class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
    val textViewId = itemView.findViewById<TextView>(R.id.job_id)
    val textViewArea = itemView.findViewById<TextView>(R.id.area)
    val textViewCarType = itemView.findViewById<TextView>(R.id.car_type)
    val textViewCarName = itemView.findViewById<TextView>(R.id.car_name)
    val textViewDutyHours = itemView.findViewById<TextView>(R.id.duty_hours)
    val textViewWeeklyOff = itemView.findViewById<TextView>(R.id.weekly_off)
    val textViewDriverAge = itemView.findViewById<TextView>(R.id.driver_age)
    val textViewDriverExperience = itemView.findViewById<TextView>(R.id.driving_experience)
    val textViewOutstationDays = itemView.findViewById<TextView>(R.id.outstation_days)
    val textViewDutyDetails = itemView.findViewById<TextView>(R.id.duty_details)
    val button = itemView.findViewById<Button>(R.id.apply_job)

}}

现在我必须如何在 kotline 中调用 sendOrder() 方法

【问题讨论】:

  • 在activity中实现接口
  • 在适配器中创建一个公共方法。然后在上面提到的 onclicklistner 中调用该方法。然后在您的主要活动中,您可以在初始化自定义适配器时覆盖该方法。
  • 你能举个例子吗?
  • @SarthakMittal 完成了它在活动中初始化适配器时抛出错误

标签: android kotlin


【解决方案1】:

最好创建一个侦听器并将其传递给适配器。

界面

interface ActivityInteractor {
    fun onInteraction(data: Any?)
}

在您的活动中实现接口

class MainActivity : Activity(), ActivityInteractor {

    override fun onCreate(savedInstance : Bundle) {
        CustomAdapterJob(jobList, this)
    }

    override fun onInteraction(data: Any?) {
        // you can do any activity related tasks here
        sendOrder()
    }
}

接受适配器中的侦听器

class CustomAdapterJob(val jobList: ArrayList<JobData>, val activityInteractor: ActivityInteractor) : RecyclerView.Adapter<CustomAdapterJob.ViewHolder>() {
    holder?.button?.setOnClickListener( View.OnClickListener () {
        Log.d("TAG", "job list position : ${jobList[position].id}")
        var id = jobList[position].id
        val p = Pattern.compile("-?\\d+")
        val m = p.matcher(id)
        while (m.find()) {
            System.out.println(m.group())
            //sendOrder()
            activityInteractor.onInteraction(jobList[position].id)
        }
    });
}

您可以在活动中实现 onClickListener 并将其作为参数传递给适配器类,而不是创建新接口。在适配器中,您可以将此 onClick 侦听器设置为您的按钮。

使用 kotlin 数据绑定概念来避免像 findViewById 这样的样板代码。请检查这个link

【讨论】:

    【解决方案2】:

    首先你需要创建一个上下文:

    private val context: Context
    

    然后将此上下文以及您可能拥有的其他变量添加到您的适配器构造函数中:

    class Adapter(..., context: Context)
    

    在你的while循环中:

    while (m.find()) {
        System.out.println(m.group)
        if (context is MainActivity)
        {
            (context as MainActivity).SendOrder()
        }
    }
    

    对任何语法错误等表示歉意。我的 Kotlin 还是有点粗糙。

    【讨论】:

    • 它给了我一个错误 unresolved reference SenderOrder
    • 我可能错过了一些东西,因为我刚刚将 Java 转换为 Kotlin。如果 Kotlin 以其他方式处理引用,我不知道
    【解决方案3】:

    最简单的解决方案是将您的活动作为回收站视图的参数。然后你可以轻松调用该函数。但显然这不是一个很好的方法,所以你应该更喜欢以下。

    创建一个由您的活动实现并调用而不是活动方法的接口。在接口函数的实现中,您可以调用活动函数或任何您喜欢的函数。由于它是由活动本身实现的,因此您可以完全访问整个活动上下文。

    已经回答了如何实现此功能的简短示例here

    【讨论】:

    • 它在初始化适配器说一些关于监听器的事情时在活动中给出错误
    • @zebapathan 那么您需要发布该错误并寻求帮助解决它! :)
    【解决方案4】:

    你可以这样做:

    holder?.button?.setOnClickListener( View.OnClickListener (){
        Log.d("TAG", "job list position : ${jobList[position].id}")
        var id = jobList[position].id
        val p = Pattern.compile("-?\\d+")
        val m = p.matcher(id)
        while (m.find()) {
            System.out.println(m.group())
             mySendOrder()
        }
    });
    
    public void mySendOrder(){
    }
    

    然后在主要活动中:

    yourCustomAdapter = new YourCustomAdapter(){
    public void mySendOrder(){
        sendOrder();
      }
    }
    

    【讨论】:

    • 表示 yourCustomAdapter 没有伴随对象,因此必须在此处初始化 @line yourCustomAdapter = new YourCustomAdapter(){
    • 你能在你初始化适配器的地方显示你的代码
    【解决方案5】:

    如果您的适配器中不需要 Context 或 Activity 对象。您可以将回调作为参数传递。可能是这样的

    class MyAdapter(private val sendOrder: () -> Unit = {}) : BaseAdapter() {
        fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
            sendOrder()
        }
    }
    

    然后在Activity中实现回调

    fun onCreate(...) {
        recyclerView.adapter = MyAdapter() {
            // Do something
        }
    }
    

    【讨论】:

    • 我应该在 recyclerView.adapter = MyAdapter() { // 做点什么 } 中写什么。这将是我的 sendOrder 方法??
    • 它在活动中说没有为参数作业列表传递值我的适配器是类 CustomAdapterJob(val jobList: ArrayList, private val sendOrder: () -> Unit = {}): RecyclerView.Adapter(){
    猜你喜欢
    • 1970-01-01
    • 2013-04-26
    相关资源
    最近更新 更多