我有一个顶级ViewGroup,我称它为SliderView,我想在其中检测滑动。这通常可以正常工作,但是一个奇怪的失败仍然存在。
SliderView的本质是重写onInterceptTouchEvent,并且在用户实际滑动后,返回“true”以防止其他 View 占用MotionEvent。这是一段代码:
public class SliderView extends ViewGroup
{
enum MoveState { MS_NONE, MS_HSCROLL, MS_VSCROLL };
private MoveState moveState = MoveState.MS_NONE;
... other code ...
public boolean onInterceptTouchEvent(MotionEvent e)
{
final int action = e.getAction();
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
moveState = MoveState.MS_NONE;
break;
case MotionEvent.ACTION_MOVE:
if (moveState == MoveState.MS_NONE)
{
if (motion is horizontal)
{
moveState = MoveState.MS_VSCROLL;
return true;
}
else
moveState = MoveState.MS_VSCROLL; // let child window handl MotionEvent
}
else if (moveState == MoveState.MS_HSCROLL)
return true; // don't let children see motion event.
}
return super.onInterceptTouchEvent (e);
}
... other code ...
}
据我了解,我的SliderView(最外面的 View )应始终接收onInterceptTouchEvent。在我的一项测试中,顶级子级是A。但是,在以下情况下,情况似乎并非如此。
当顶级子级是ScrollView时,onInterceptTouchEvent将获得ACTION_MOVE,而我的代码将执行我想要的操作。在另一种情况下,顶级子对象是LinearLayout,则有时会失败:它始终会获得ACTION_DOWN,但仅当用户触摸LinearLayout内的小部件时才会获得ACTION_MOVE;如果触摸空白区域,则只有ACTION_DOWN通过。
我会注意到,它的行为就像是在SliderView外部发生了失败案例触摸一样。但是,如果是这种情况,为什么我会收到ACTION_DOWN事件?
第二点:查看ScrollView的源代码,我看到它检查了“inChild”;我还没有弄清楚这是做什么用的,以及它可能如何与之相关。
最佳答案
由于user123321的回答here