拦截触摸事件并根据运动事件状态重新引导它

我在Android中创建了一个从RelativeLayout继承的自定义视图。 在这个视图内部是一个OverScroller,当触摸事件发生时用于处理视图的滚动:

class MyCustomView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : RelativeLayout(context, attrs, defStyleAttr) { constructor(context: Context) : this(context, null, 0) constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0) private val scroller = OverScroller(context, FastOutLinearInInterpolator()) private var currentY = 0 private val gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() { override fun onDown(event: MotionEvent?): Boolean { // Stop the current scroll animation scroller.forceFinished(true) // Invalidate the view ViewCompat.postInvalidateOnAnimation(this@MyCustomView) return true } override fun onScroll(event1: MotionEvent?, event2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean { scroller.forceFinished(true) currentY -= distanceY.toInt() ViewCompat.postInvalidateOnAnimation(this@MyCustomView) return true } override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean { // Stop any scrolling scroller.forceFinished(true) scroller.fling(0, currentY, 0, velocityY.toInt(), 0, 0, -5000 + height, 0) // Invalidate the view ViewCompat.postInvalidateOnAnimation(this@MyCustomView) return true } }) @SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(event: MotionEvent?): Boolean { if (event == null) return false // Return the value from the gesture detector return gestureDetector.onTouchEvent(event) } override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) // Draw stuff to canvas, using currentY as origin } override fun computeScroll() { // Call to super class method super.computeScroll() if (scroller.computeScrollOffset()) { currentY = scroller.currY } // Invalidate the view ViewCompat.postInvalidateOnAnimation(this@MyCustomView) } } 

这工作正常。 接下来,我添加了一个RelativeLayout视图组来保存一个充满的单元格的负载。 这些单元格是可点击的。 现在,当我尝试通过第一次触摸其中一个膨胀的单元格来启动滚动时,单元格会吞下单击事件(父视图与滚动器永远不会调用onTouchEvent调用,因此不会滚动)。

重要提示:保存单元格的RelativeLayout视图组是MyCustomViewchild视图。

我已经尝试覆盖MyCustomView中的onInterceptTouchEvent ,以拦截触发事件,然后将其分派到视图中,如下所示:

 override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { if (event == null) return false if (event.action == MotionEvent.ACTION_UP) { if (event.historySize > 0) { val startY = event.getHistoricalY(0) val endY = event.getHistoricalY(event.historySize - 1) val distance = Math.abs(endY - startY).toInt() if (distance == 0) { // Consider this a click (so don't swallow it return false } } } // Ok this isn't a click, so call this views onTouchEvent return this.onTouchEvent(event) } 

然后,我确定触摸事件的动作代码是ACTION_UP ,如果是我计算ACTION_DOWNACTION_UP之间的总距离,如果它在一个足够小的范围内,我把它作为一个点击和调用super.onInterceptTouchEvent(event) (这如果事件在单元格上,将会点击一个膨胀的单元格,否则最终会调用我的onTouchEvent来处理滚动。如果事件的动作代码不是ACTION_UP或者移动的距离不够小,它会返回this.onTouchEvent(event)

我遇到的问题是我的解决方案无法正常工作,滚动仍然无法启动时,在一个膨胀的单元格上面开始滚动。

有谁知道我错过了什么?