问题描述
我想弄清楚如何在各种类中安排我的 onInterceptTouchEvent
和 onTouchEvent
覆盖。
ButtonContainer
|
|-----------+
Button BitContainer
|
------------|
View1 View2
ButtonContainer 和 BitContainer 是 RelativeLayouts,Button、View1 和 View2 都是具有可绘制圆形背景的图像视图。 View1 和 View2 最初不可见。
目标是让 ButtonContainer 通过使 view1 和 view2 可见来响应初始 ACTION_DOWN
事件。在 ACTION_MOVE
事件上,如果触摸从 Button 移动到 View1,则应调用 View1 onTouchEvent 方法。
我想我可以在 ButtonContainer 上使用 onInterceptTouchEvent 并在 ACTION_DOWN
的情况下将其设置为 true,但在所有其他情况下将其设置为 false。这不应该阻止 ACTION_MOVE
事件直接进入 ButtonContainer onTouch 并让它遍历树吗?如果是这样,那么 ACTION_MOVE
事件将遵循通常的事件流并被其他视图检测到,即视图 1 和 2。
无论我做什么,都无法让 view1 或 2 中的 onTouchEvent 方法响应 ACTION_MOVE 手势。
该事件是否可能在其他地方被发现?我注意到,如果视图 1 可见并且低于 ACTION_DOWN
上的 TouchEvent 位置,它会检测到后续的 ACTION_MOVE
事件……但是如果 TouchEvent 发生在视图 2 上或按钮,则视图 1 不会响应 ACTION_MOVE
。
编辑:好的,所以我读了更多,似乎如果一个对象'不消耗 ACTION_DOWN 事件,那么它不会消耗任何进一步的事件(出于效率原因)'...
我认为消费意味着“直接在下方”而不是“是 ViewGroup 的一部分”。那是对的吗?有没有办法将事件传递给 View1,以便它可以收到 ACTION_MOVE 的通知?
解决方法
对于其他面临此问题的人,诀窍是手动进行事件调度。
Button1 从 OnTouchEvent
返回 true 如果 action = ACTION_DOWN.
当它是 ACTION_MOVE
时,则返回 false。
当 action 为 onInterceptTouchEvent
时,ButtonContainer 在 ACTION_MOVE
上返回 true,然后调用 BitContainer 的 dispatchTouchEvent
,它使用 for 循环在所有 t 的子视图上调用 dispatchTouchEvent
>
从那里开始,您现在可以在每个子视图中编写一个方法来检查触摸事件的 x 位置是否在它们自己的 getLocationOnScreen()
坐标内。
这里以ButtonContainer上的onInterceptTouch事件,BitContainer上的dispatchTouchEvent为例:
按钮容器
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
if (ev != null) {
if (ev.action == MotionEvent.ACTION_MOVE) {
bitContainer.dispatchTouchEvent(ev)
return true
}
}
return super.onInterceptTouchEvent(ev)
}
比特容器
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (ev != null) {
if (ev.action == MotionEvent.ACTION_MOVE) {
for (i in 0 until this.getChildCount()) {
this.getChildAt(i).dispatchTouchEvent(ev)
}
}
}
return super.dispatchTouchEvent(ev)
}