RecyclerView 子控件点击事件封装

246 阅读1分钟

RecyclerView 子控件点击事件的封装与使用

前言

在版本开发的过程中,遇到了需要点击RecyclerView itemView中子控件的需求,但询问了小伙伴之后发现,既不能直接在onBind方法中直接setOnClickListener,也没有其他方法可以直接设置点击事件,只能通过回调实现,稍嫌麻烦,特别是遇到点击事件埋点时,需要传递很多参数。所以萌发了对RecyclerView子控件点击封装的想法,把点击事件抛到UI层,而不需要关心内部做了什么逻辑。

图例(子控件指椭圆所画控件):

思路

对需要设置点击事件的子控件进行保存,统一设置回调

  • 需要设置点击事件的View集合
//需要设置点击事件的空间id集合

private val clickChildViewIds = linkedSetOf<Int>()
  • 添加需要点击事件的View
fun addOnChildClickListener(@IdRes vararg viewIds: Int) {

    viewIds.forEach {

 clickChildViewIds.add(it)

    }

}
  • 点击事件回调
//点击事件回调,参数有holder, position,需要点击的view

typealias OnItemChildClickListener = (holder: BaseHolder, position: Int, view: View) -> Unit
  • 点击事件回调赋值
fun setOnItemChildClickListener(onClickListener: OnItemChildClickListener) {

    onItemClickListener = onClickListener

}
  • 在onCreateViewHolder中间进行点击事件的设置
onItemClickListener?.let { listener ->

 for (id in clickChildViewids) {

        val childView: View = holder.itemView.findViewById(id) ?: continue

        if (childView.isClickable) childView.isClickable = true



        childView.setOnClickListener {

 val position = holder.adapterPosition

 if (position == RecyclerView.NO_POSITION) {

                return@setOnClickListener

            }

            listener.invoke(holder, position, childView)

        }

 }

 }

具体使用

使用的时候很简单,在UI层注册ViewId之后,就可以设置点击事件了

//注册需要点击事件的View

adapter.addOnChildClickViewIds(R.id.tv_name)



//设置点击事件的监听

adapter.setOnItemChildClickListener { holder, position, view ->

 when (view.id) {

        R.id.tv_name -> {

            val name = adapter.items[position].name

            Toast.makeText(this, name + position, Toast.LENGTH_SHORT).show()

        }

    }

 }

优点

  • 可以避免繁杂的参数传递
  • 新增或减少控件点击事件,只需修改注册id即可。
  • 解耦adapter中的逻辑。