java onInterceptTouchEvent 只获得 ACTION_DOWN
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13283827/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
onInterceptTouchEvent only gets ACTION_DOWN
提问by user123321
Why do ViewGroup
's only get ACTION_DOWN
in the onInterceptTouchEvent
? According to the docs, as long as false is returned it should receive all the event types.
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent%28android.view.MotionEvent%29Point #3.
为什么ViewGroup
“唯一得到ACTION_DOWN
的onInterceptTouchEvent
?根据文档,只要返回 false,它就应该接收所有事件类型。
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent%28android.view.MotionEvent%29第 3 点。
Sample code:
示例代码:
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new Container(this));
}
private class Container extends LinearLayout {
public Container(Context context) {
super(context);
setBackgroundColor(0xFF0000FF);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i(TAG, "onInterceptTouchEvent");
int action = ev.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.i(TAG, "onInterceptTouchEvent.ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.i(TAG, "onInterceptTouchEvent.ACTION_MOVE");
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
Log.i(TAG, "onInterceptTouchEvent.ACTION_UP");
break;
}
return super.onInterceptTouchEvent(ev);
}
}
}
回答by user123321
I'll answer my own question: 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.
我将回答我自己的问题:只有当父视图有一个从 onTouchEvent 返回“true”的子视图时,才会调用 onInterceptTouchEvent。一旦孩子返回真,父母现在有机会拦截该事件。
回答by hyyou2010
I get the same problem. I had read many posts about it:
onInterceptTouchEvent only gets ACTION_DOWN
onInterceptTouchEvent's ACTION_UP and ACTION_MOVE never gets called
onInterceptTouchEvent, onTouchEvent only see ACTION_DOWN
onInterceptTouchEvent never receives action_move
我遇到同样的问题。我读过很多关于它的帖子:
onInterceptTouchEvent only gets ACTION_DOWN
onInterceptTouchEvent's ACTION_UP 和 ACTION_MOVE 永远不会被调用
onInterceptTouchEvent, onTouchEvent only see ACTION_DOWN
onInterceptTouchEvent never received action_move
I also had read android doc:
http://developer.android.com/training/gestures/viewgroup.html
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)
我也读过 android 文档:
http: //developer.android.com/training/gestures/viewgroup.html
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.运动事件)
All answers are same. I tried many times, always not get onInterceptTouchEvent
() be called if not down event.
所有的答案都是一样的。我试了很多次,总是得不到onInterceptTouchEvent() if not down 事件被调用。
I read source code, I guess that something is changed:
我阅读了源代码,我想有些东西已经改变了:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
}
boolean handled = false;
if (onFilterTouchEventForSecurity(ev)) {
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
// Handle an initial down.
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
cancelAndClearTouchTargets(ev);
resetTouchState();
}
// Check for interception.
final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
} else {
// There are no touch targets and this action is not an initial down
// so this view group continues to intercept touches.
intercepted = true;
}
According above code, onInterceptTouchEvent(ev)
is only be called when MotionEvent.ACTION_DOWN
, this is what we tried and found. So, what I guess is, the code is changed, but doc not.
根据上面的代码,onInterceptTouchEvent(ev)
只被调用 when MotionEvent.ACTION_DOWN
,这是我们尝试和发现的。所以,我猜是,代码已更改,但文档未更改。
If you want spy or monitor all the events include those been sent to child views, you can override dispatchTouchEvent()
like this:
如果您想监视或监视所有事件,包括发送到子视图的事件,您可以dispatchTouchEvent()
像这样覆盖:
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
MyLog.d(MyLog.DEBUG, "dispatchTouchEvent(): "+event.getAction());
if (isEnabled()) {
MyLog.d(MyLog.DEBUG, "dispatchTouchEvent()2: "+event.getAction());
processEvent(event);//here you get all events include move & up
super.dispatchTouchEvent(event);
return true; //to keep receive event that follow down event
}
return super.dispatchTouchEvent(event);
}
I have the runnable code at: https://github.com/maxyou/gesturebutton/blob/master/src/com/maxproj/gesturebutton/GestureButtonLayout.java
我有可运行的代码:https: //github.com/maxyou/gesturebutton/blob/master/src/com/maxproj/gesturebutton/GestureButtonLayout.java
回答by yoAlex5
The official doc
官方文档
Activity.dispatchTouchEvent(MotionEvent)
- This allows your Activity to intercept all touch events before they are dispatched to the window.
ViewGroup.onInterceptTouchEvent(MotionEvent)
- This allows a ViewGroup to watch events as they are dispatched to child Views. It is recursively function (from parent to parent)
ViewParent.requestDisallowInterceptTouchEvent(boolean)
- Call this upon a parent View to indicate that it should not intercept touch events with onInterceptTouchEvent(MotionEvent).
Activity.dispatchTouchEvent(MotionEvent)
- 这允许您的 Activity 在将它们分派到窗口之前拦截所有触摸事件。
ViewGroup.onInterceptTouchEvent(MotionEvent)
- 这允许 ViewGroup 在事件被分派到子视图时观看事件。它是递归函数(从父级到父级)
ViewParent.requestDisallowInterceptTouchEvent(boolean)
- 在父视图上调用它以指示它不应使用 onInterceptTouchEvent(MotionEvent) 拦截触摸事件。