Android Kotlin 子 onClick 阻止父 OnTouch

标签 android onclicklistener ontouchlistener kotlin

我有这个布局层次结构:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.xxxxxx.Widget
        android:id="@+id/widget1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <com.xxxxxx.Widget
        android:id="@+id/widget2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    </LinearLayout>
</LinearLayout>

我有父 LinearLayout 的触摸事件,如下所示:
parent.setOnTouchListener(myCustomTouchParent)

    class MyCustomTouchParent(ctx: Context): View.OnTouchListener {

        private var isScrollingDown = false
        private var isScrollingUp = false
        private val myGestureDetected = GestureDetector(ctx, MyGestureListener())

        var onRecyclerViewMovingDown: (() -> Unit)? = null

        override fun onTouch(p0: View?, e: MotionEvent): Boolean {
            myGestureDetected.onTouchEvent(e)

            when(e.action){
                MotionEvent.ACTION_UP -> {
                    if (isScrollingDown) {
                        onRecyclerViewMovingDown?.invoke()
                    }
                }

                MotionEvent.ACTION_DOWN -> {
                    Log.i("TAg", "Action Down")
                    isScrollingDown = false
                    isScrollingUp = false

                }
            }
            return true
        }

        inner class MyGestureListener: GestureDetector.SimpleOnGestureListener() {
            override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
                if(e2.y - e1.y > 0){
                    isScrollingUp = true
                } else if(e2.y - e1.y < 0){
                    isScrollingDown = true
                }
                return super.onScroll(e1, e2, distanceX, distanceY)
            }


        }
    }

基本上,这将检测父级上的“向上滚动”事件,并执行一些动画。问题是,一旦我为 widget1 和 widget2 设置了点击监听器,父级的触摸事件就不再起作用。有什么解决方法吗?

最佳答案

唯一对我有用的东西:在父 LinearLayout 中,拦截触摸,调用 onTouchEvent 并返回 false:

override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        onTouchEvent(ev)
        return false
    }

将带有 Gesture Detector 类的 TouchInterceptor 移动到父 onTouchEvent:
override fun onTouchEvent(e: MotionEvent): Boolean {
            myGestureDetected.onTouchEvent(e)

            when(e.action){
                MotionEvent.ACTION_UP -> {
                    if (isScrollingDown) {
                        onRecyclerViewMovingDown?.invoke()
                    }
                }

                MotionEvent.ACTION_DOWN -> {
                    isScrollingDown = false
                    isScrollingUp = false

                }
            }
            return super.onTouchEvent(e)
        }

我不知道是否有更好的解决方案,但是这个让我先处理父级的触摸事件,然后将触摸传递给子级。在那里你可以设置你的点击监听器。

另外,如果你不设置点击监听器,包含可点击项目的触摸区域将不会触发触摸。所以,更好的设置
clickable=true

在所有项目中,然后仅在需要时设置监听器。

关于Android Kotlin 子 onClick 阻止父 OnTouch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36065388/

相关文章:

java - Maven - 与 JavaME、JavaSE 和 Android 模块共享多模块项目的记录器

java - 如何为带有变量的按钮定义命令

android - Android OnClick和onTouch:哪个更好?

java - parseInt() 方法是否删除所有零?

java - 仅在生产版本中应用加载时出现 RuntimeException

android - 如何在android中的单元测试和仪器测试之间共享资源?

android - 左右 Android 抽屉导航相互重叠

android - 如何在不抬起手指的情况下撤销 `requestDisallowInterceptTouchEvent(false)`(Action.UP 或 Cancel)?

android - 用于 TableRow 内多个 TextView 的 onTouchListener

安卓权限