我有一个*ViewGroup,我称之为SliderView,我想在其中检测滑动.这主要是有效的,但一个奇怪的失败仍然存在.
SliderView的本质是覆盖onInterceptTouchEvent,一旦用户实际滑动,返回“true”以防止其他视图查看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(最外面的视图)应该总是接收onInterceptTouchEvent.在我的一个测试中,*子节点是a但是,在下面的情况中,这似乎不是.
当*子项是ScrollView时,onInterceptTouchEvent获取ACTION_MOVE并且我的代码执行我想要的操作.在另一种情况下,*子级是LinearLayout,它有时会失败:它总是获得ACTION_DOWN,但只有当用户触摸LinearLayout内的小部件时才获得ACTION_MOVE;如果触摸空白区域,则仅通过ACTION_DOWN.
我会注意到它的行为就好像在SliderView之外发生了故障情况触摸.但是,如果是这种情况,为什么我会得到ACTION_DOWN事件?
第二个注意:查看ScrollView的源代码,我看到它检查“inChild”;我还没弄清楚这是什么以及它可能如何相关.
解决方法:
由于user123321 here的答案
onInterceptTouchEvent only get called if the parent has a child view which returns “true” from onTouchEvent. Once the child returns true, the parent now has a chance to intercept that event