我有这个布局层次结构:
<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>
我已触摸Parent 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设置了一个点击监听器,父级的触摸事件就不再有效了。有没有解决方法呢?
答案 0 :(得分:1)
对我来说唯一有用的东西:在父级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
在所有项目中,然后只在需要时设置监听器。
答案 1 :(得分:0)
您必须覆盖子视图上的onTouchListeners并返回false,这将使它们不会覆盖其父ontouch。
widget1.onTouch { view, motionEvent -> return@onTouch false }
widget2.onTouch { view, motionEvent -> return@onTouch false }