我正在使用下面的 OnItemTouchListener 类检测 RecyclerView 中的点击事件。然而,当使用 DrawerLayout 时,这种方法效果不佳。如果我滑动以打开 DrawerLayout/NavigationView,我的 OnItemTouchListener 也会收到事件并执行 onLongClick 操作。
如果我使用 ViewHolders 的 View.OnLongClick,则不会发生这种情况。View 的 OnLongClickListener 触发 LongClick 事件之前会先检查拖动操作是否为长按,还是手势打开抽屉的操作?
如果我使用 ViewHolders 的 View.OnLongClick,则不会发生这种情况。View 的 OnLongClickListener 触发 LongClick 事件之前会先检查拖动操作是否为长按,还是手势打开抽屉的操作?
class OnItemTouchListener(context: Context, recyclerView: RecyclerView, private var onTouchCallback: ItemTouchListener) : RecyclerView.OnItemTouchListener {
//region Variables
private val gestureDetector: GestureDetector
//endregion
init {
gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent?): Boolean {
return true
}
override fun onLongPress(e: MotionEvent?) {
val child: View? = recyclerView.findChildViewUnder(e!!.x, e.y)
if (child != null) {
onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), e)
}
super.onLongPress(e)
}
})
}
//region TouchHandler
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
val child = rv.findChildViewUnder(e.x, e.y)
if (child != null && gestureDetector.onTouchEvent(e)) {
onTouchCallback.onItemClick(child, rv.getChildLayoutPosition(child), e)
}
return false
}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
}
override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {
}
//endregion
interface ItemTouchListener {
fun onItemClick(view: View, pos: Int, e: MotionEvent)
fun onItemLongClick(view: View, pos: Int, e: MotionEvent)
}
companion object {
fun isViewClicked(container: View, @IdRes viewId: Int, e: MotionEvent): Boolean {
val view = container.findViewById<View>(viewId)
val rect = Rect()
view.getGlobalVisibleRect(rect)
return view.isVisible && rect.contains(e.rawX.toInt(), e.rawY.toInt())
}
}
}