You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何在RecyclerView Adapter内实现按钮的onClickListener

RecyclerView列表项按钮点击事件实现方案

推荐在ViewHolder中绑定点击事件,而非onBindViewHolder,避免重复创建监听器带来的性能损耗

实现思路

通过自定义回调接口将点击事件传递到Activity/Fragment层处理,既可以降低Adapter的耦合度,也能方便获取当前点击条目对应的业务数据。

具体实现步骤

  • 1、在Adapter内部定义点击事件回调接口
  • 2、修改Adapter构造函数,接收回调接口实例
  • 3、在ViewHolder初始化时绑定按钮点击事件,触发时调用回调接口
  • 4、在使用Adapter的页面实现回调接口,编写具体的点击业务逻辑

修改后的完整Adapter代码

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.bloodbankcompany.R
import com.example.bloodbankcompany.User2

class MyAdapter2(
    private val userList: ArrayList<User2>,
    // 新增点击回调参数
    private val onNotifyButtonClickListener: OnNotifyButtonClickListener
): RecyclerView.Adapter<MyAdapter2.MyViewHolder>(){

    // 自定义点击回调接口
    interface OnNotifyButtonClickListener {
        fun onNotifyClick(user: User2, position: Int)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter2.MyViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item2,parent,false)
        return MyViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: MyAdapter2.MyViewHolder, position: Int) {
        val user:User2 = userList[position]
        holder.name.text= user.name
        holder.phone.text= user.phone
        holder.address.text =user.address
        holder.bloodGroup.text= user.bloodgroup
        holder.io = user.id
    }

    override fun getItemCount(): Int {
        return userList.size
    }

    public class MyViewHolder(itemView : View): RecyclerView.ViewHolder(itemView){
        val name : TextView = itemView.findViewById(R.id.tvfirstname1)
        val phone :TextView= itemView.findViewById(R.id.tvphone11)
        val address : TextView= itemView.findViewById(R.id.tvaddress1)
        val bloodGroup: TextView =itemView.findViewById(R.id.tvbloodg1)
        val id: TextView = itemView.findViewById(R.id.tvid)
        var io: String? = ""
        var button: Button = itemView.findViewById(R.id.btn_notify)

        init {
            // ViewHolder初始化时仅绑定一次点击事件,性能更优
            button.setOnClickListener {
                val currentPosition = absoluteAdapterPosition
                // 避免ViewHolder位置无效时触发异常
                if (currentPosition != RecyclerView.NO_POSITION) {
                    val clickUser = userList[currentPosition]
                    onNotifyButtonClickListener.onNotifyClick(clickUser, currentPosition)
                }
            }
        }
 }
}

页面调用示例(以Activity为例)

// 初始化Adapter时传入回调实现
val myAdapter = MyAdapter2(userList, object : MyAdapter2.OnNotifyButtonClickListener {
    override fun onNotifyClick(user: User2, position: Int) {
        // 此处编写具体的点击逻辑,比如跳转页面、发起通知请求、弹出提示等
        Toast.makeText(this@YourActivity, "你点击了${user.name}的通知按钮", Toast.LENGTH_SHORT).show()
    }
})
// 给RecyclerView设置Adapter
recyclerView.adapter = myAdapter

说明:如果有特殊需求需要在onBindViewHolder中处理点击也可以实现,但是每次条目绑定都会重新设置监听器,会产生多余的性能开销,非必要不推荐。

内容的提问来源于stack exchange,提问作者user16493824

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 12:18:02