Kotlin如何实现RecyclerView Adapter多回调传回Activity/Fragment
RecyclerView多回调实现方案
完全支持在Adapter中定义多个独立回调,你写的Adapter构造函数核心思路正确,问题出在两处:一是初始化传参的Kotlin语法使用错误,二是存在小的命名不一致问题。
错误原因
你在Activity中初始化Adapter时,把多段逻辑塞在了同一个尾Lambda(Trailing Lambda)大括号里。Kotlin的语法规则下,这种写法只会把大括号内的内容作为构造函数最后一个参数传入,其余几个回调参数完全没有赋值,会直接触发编译错误。
另外你定义的回调参数名是checkedAsComplete,初始化时写的是checkAsComplete,命名不统一也会导致引用失败。
正确实现步骤
1. 优化Adapter代码
首先把不需要修改的context参数改成val(避免不必要的可变引用),统一回调命名,在ViewHolder中给对应操作控件绑定点击事件触发回调:
class ProductAdapter( private val context: Context, private val deleteProduct: (ItemTable) -> Unit, private val editProduct: (ItemTable) -> Unit, private val viewProduct: (ItemTable) -> Unit, private val checkAsComplete: (ItemTable) -> Unit ): RecyclerView.Adapter<ProductAdapter.ItemProductViewHolder>() { inner class ItemProductViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { // 绑定布局里的操作控件,按你自己的布局ID调整 private val btnDelete: Button = itemView.findViewById(R.id.btn_delete) private val btnEdit: Button = itemView.findViewById(R.id.btn_edit) private val btnView: Button = itemView.findViewById(R.id.btn_view) private val cbComplete: CheckBox = itemView.findViewById(R.id.cb_mark_complete) fun bind(item: ItemTable) { btnDelete.setOnClickListener { deleteProduct(item) } btnEdit.setOnClickListener { editProduct(item) } btnView.setOnClickListener { viewProduct(item) } cbComplete.setOnCheckedChangeListener { _, checked -> if (checked) checkAsComplete(item) } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemProductViewHolder { // 原有加载列表项布局逻辑保持不变 val view = LayoutInflater.from(context).inflate(R.layout.item_product, parent, false) return ItemProductViewHolder(view) } override fun onBindViewHolder(holder: ItemProductViewHolder, position: Int) { // 原有列表数据获取逻辑保持不变,调用bind方法绑定事件 val currentItem = currentList[position] holder.bind(currentItem) } override fun getItemCount(): Int = currentList.size }
2. 修正Activity/Fragment侧初始化代码
多函数类型参数不能全部用尾Lambda传入,需要逐个给构造参数赋值,如果方法签名和回调一致,还可以直接用方法引用简化代码:
// 常规写法 val adapter = ProductAdapter( context = this, deleteProduct = { item -> deleteProduct(item) }, editProduct = { item -> editProduct(item) }, viewProduct = { item -> viewProduct(item) }, checkAsComplete = { item -> checkAsComplete(item) } ) // 更简洁的方法引用写法(要求Activity/Fragment里的对应方法参数、返回值和回调完全匹配) val adapter = ProductAdapter( context = this, deleteProduct = ::deleteProduct, editProduct = ::editProduct, viewProduct = ::viewProduct, checkAsComplete = ::checkAsComplete )
可选优化:回调聚合写法
如果后续列表项操作继续增多,多个构造参数会让代码显得冗余,可以把所有回调封装到一个数据类中统一传递,后续维护更方便:
// 单独定义回调聚合类 data class ProductItemActions( val onDelete: (ItemTable) -> Unit, val onEdit: (ItemTable) -> Unit, val onView: (ItemTable) -> Unit, val onMarkComplete: (ItemTable) -> Unit ) // Adapter修改为只接收一个聚合回调参数 class ProductAdapter( private val context: Context, private val actions: ProductItemActions ): RecyclerView.Adapter<ProductAdapter.ItemProductViewHolder>() { // 内部调用时对应写actions.onDelete(item)、actions.onEdit(item)即可,其余逻辑不变 } // 初始化写法 val adapter = ProductAdapter( context = this, actions = ProductItemActions( onDelete = ::deleteProduct, onEdit = ::editProduct, onView = ::viewProduct, onMarkComplete = ::checkAsComplete ) )
注意:在Fragment中使用时,Context参数请传
requireContext(),不要直接传Fragment实例this,避免生命周期不一致导致的内存泄漏。
内容的提问来源于stack exchange,提问作者Think_Twice
相关产品推荐
相关产品推荐

