onInterceptTouchEvent,onTouchEvent仅查看ACTION_DOWN
我有一个顶级ViewGroup,我称它为SliderView,我想在其中检测滑动.这通常可以正常工作,但是一个奇怪的失败仍然存在.
I have a top level ViewGroup, which I call SliderView, in which I want to detect swiping. This is mostly working, but one weird failure persists.
SliderView的本质是重写onInterceptTouchEvent,并且在用户实际滑动后,返回"true"以防止其他视图占用MotionEvent.这是一段代码:
The essence of SliderView is to override onInterceptTouchEvent and, once the user is actually swiping, return "true" to prevent other views from seing the MotionEvent. Here is a snip of code:
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.但是,在以下情况下,这似乎不是.
It is my understanding that my SliderView (which is the outermost view) should always recevie onInterceptTouchEvent. In one of my tests, where the top level child is a However, in the following case, this appears not to be.
当顶级子级是ScrollView时,onInterceptTouchEvent将获得ACTION_MOVE,而我的代码将执行我想要的操作.在另一种情况下,顶级子对象是LinearLayout,则有时会失败:它始终会获得ACTION_DOWN,但仅当用户触摸LinearLayout内的小部件时才会获得ACTION_MOVE;如果触摸空白区域,则只有ACTION_DOWN通过.
When the top level child is a ScrollView, onInterceptTouchEvent gets ACTION_MOVE and my code does what I want. In another case, where the top level child is a LinearLayout, it fails sometimes: it always gets ACTION_DOWN but gets ACTION_MOVE only if the user touches a widget inside the LinearLayout; if touching blank area, only ACTION_DOWN comes through.
我会注意到,它的行为就像是在SliderView外部发生了失败案例触摸一样.但是,如果是这种情况,为什么我会收到ACTION_DOWN事件?
I'll note that it behaves as if the fail-case touches are happening outside the SliderView. However, if that were the case, why would I get the ACTION_DOWN events?
第二条注释:查看ScrollView的源代码,我看到它检查了"inChild";我还没有弄清楚这是干什么的,它可能有什么用.
Second note: looking at the source code for ScrollView, I see it checking for "inChild"; I have not figured out what that's for and how it might be relevant.
由于user123321的回答这里
Due to the answer of user123321 here
onInterceptTouchEvent仅在父级具有从onTouchEvent返回"true"的子视图时才被调用.一旦孩子返回true,父母现在就有机会拦截该事件
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