如何给RecyclerView高效的设置点击事件?

1,257 阅读1分钟

recyclerView虽然没有像listView那样提供了一个onItemClickListener,但是提供了一个触摸事件OnItemTouchListener, 同时,提供了一个findChildViewUnder(x,y)的API,可以根据触摸的坐标得到ItemView,我们再利用getChildAdapterPosition()得到 手指触摸到的位置,这里再介绍一个API,GestureDetector.SimpleOnGestureListener,利用它,我们可以很方便的实现单击和长按事件。 新建一个文件RecyclerItemClickListener,实现RecyclerView.OnItemTouchListener,再新建一个文件,OnItemClickListener,里面有两个需要复写的接口

// 因为长按事件不常用,这里我们给他个默认实现
interface OnItemClickListener {
    fun onItemClick(view: View, position: Int)
    fun onItemLongClick(view: View, position: Int){}
}

class RecyclerItemClickListener(context: Context, recyclerView: RecyclerView, var listener: OnItemClickListener) : RecyclerView.OnItemTouchListener {


        var gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
            override fun onSingleTapUp(e: MotionEvent): Boolean {
                val child = recyclerView.findChildViewUnder(e.x, e.y)
                if (child != null && listener != null) {
                    listener?.onItemClick(child, recyclerView.getChildAdapterPosition(child))
                }
                return true
            }

            override fun onLongPress(e: MotionEvent) {
                val child = recyclerView.findChildViewUnder(e.x, e.y)
                if (child != null && listener != null) {
                    listener?.onItemLongClick(child, recyclerView.getChildAdapterPosition(child))
                }
            }
        })

    override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
        val childView = rv.findChildViewUnder(e.x, e.y)
        if (childView != null && listener != null && gestureDetector!!.onTouchEvent(e)) {
            listener?.onItemClick(childView, rv.getChildAdapterPosition(childView))
            return true
        }
        return false
    }


    override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {

    }

    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {

    }


}

使用:

recyclerView?.let{
    it.addOnItemTouchListener(RecyclerItemClickListener(this,it1, object : OnItemClickListener {
                    override fun onItemClick(view: View, position: Int) {
                        // 处理点击事件
                    }
                }))
}