Перехват события касания и перенаправление его в зависимости от состояния события движения

Я создал пользовательский вид в 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 которая содержит ячейки, представляет собой child вид MyCustomView .

Я попытался переопределить onInterceptTouchEvent в MyCustomView , чтобы перехватить событие касания, прежде чем он будет отправлен на любой вид:

 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_DOWN и ACTION_UP и если он находится в небольшом диапазоне, я рассматриваю его как щелчок и вызов super.onInterceptTouchEvent(event) (который будет кликать на завышенную ячейку, если событие было в ячейке, иначе оно вызовет мой onTouchEvent который будет обрабатывать прокрутку. Если код действия события не был ACTION_UP или перемещенное расстояние не было достаточно маленьким, оно вернет this.onTouchEvent(event) .

Проблема, с которой я сталкиваюсь, заключается в том, что мое решение не работает, прокрутка по-прежнему не может быть инициирована при запуске свитка поверх накаченной ячейки.

Кто-нибудь знает, что мне не хватает?

Intereting Posts
В Kotlin, как вы изменяете содержимое списка во время итерации Android Anko с пользовательской ошибкой просмотра (Kotlin) Kotlin: Как я могу избежать автобоксинга (мусора) в делегированных свойствах? Охват кода студии Android, не показывающий классов Kotlin Kotlin – Использование Enums для извлечения Char Как реализовать проверенный конструктор в Котлине? Невозможно поймать бросок исключения после отмены Kotlin coroutine проекции не допускаются для непосредственных подтипов супертипа Android только setStackFromEnd, только если RecycleView / List больше экрана Out-projected type «ArrayList <*>» запрещает использование «public open fun add (index: Int, element: E): Unit, определенный в java.util.ArrayList ' Как я могу написать идиоматический код kotlin, который перебирает подпроцесс и обрабатывает его вывод? Как получить Kotlin KClass из строки имени класса пакета? латинит, ленивый и одноэлементный узор в котлине Компилятор Kotlin всегда сохраняет имена параметров в байт-коде? Как отключить ткань при выполнении теста