OnInterceptTouchEvent получает только ACTION_DOWN
Почему ViewGroup
получает только ACTION_DOWN
в onInterceptTouchEvent
? Согласно документам, до тех пор, пока возвращается false, он должен получать все типы событий. http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent%28android.view.MotionEvent%29 Точка № 3.
Образец кода:
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);
}
}
}
Ответы
Ответ 1
Я отвечу на свой вопрос: onInterceptTouchEvent только вызывается, если у родителя есть дочернее представление, которое возвращает "true" из onTouchEvent. Когда дочерний объект возвращает true, родитель теперь имеет возможность перехватить это событие.
![enter image description here]()
Ответ 2
У меня та же проблема. Я прочитал много постов об этом:
onInterceptTouchEvent получает только ACTION_DOWN
ACTION_UP и ACTION_MOVE onInterceptTouchEvent никогда не вызывается
onInterceptTouchEvent, onTouchEvent видят только ACTION_DOWN
onInterceptTouchEvent никогда не получает action_move
Я также читал документацию для Android:
http://developer.android.com/training/gestures/viewgroup.html
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)
Все ответы одинаковы. Я пытался много раз, всегда не получить onInterceptTouchEvent(), если не событие.
Я читаю исходный код, думаю, что-то изменилось:
@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;
}
Согласно приведенному выше коду, onInterceptTouchEvent(ev)
вызывается только тогда, когда MotionEvent.ACTION_DOWN
, это то, что мы пытались и нашли. Итак, я думаю, что код изменился, но нет.
Если вы хотите, чтобы шпион или отслеживал все события, включая те, которые были отправлены в дочерние представления, вы можете переопределить 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);
}
У меня есть исполняемый код по адресу: https://github.com/maxyou/gesturebutton/blob/master/src/com/maxproj/gesturebutton/GestureButtonLayout.java
Ответ 3
Еще одна иллюстрация потока OnTouch
![enter image description here]()
Activity.dispatchTouchEvent(MotionEvent)
- это позволяет вашей активности перехватывать все сенсорные события, прежде чем они будут отправлены в окно.
ViewGroup.onInterceptTouchEvent(MotionEvent)
- Это позволяет ViewGroup наблюдать за событиями, когда они отправляются дочерним представлениям. Это рекурсивная функция (от родителя к родителю)
ViewParent.requestDisallowInterceptTouchEvent(boolean)
- вызовите это для родительского просмотра, чтобы указать, что он не должен перехватывать события касания с помощью onInterceptTouchEvent (MotionEvent).
Полный SO ответ здесь here