OnInterceptTouchEvent никогда не получает action_move

У меня есть пользовательская ViewGroup с переопределением onInterceptTouchEvent(). Он получает ACTION_DOWN, но никогда не получает ACTION_MOVE. Я понимаю, что, если он не вернет "истину", он должен получить все MotionEvents.

ViewGroup содержит два вида: ImageView и GridLayout.

Мой код перехвата:

  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev)
  {
    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK)
    {
      case MotionEvent.ACTION_DOWN:
        logD ("DDV Intercept DOWN");
        break;
      case MotionEvent.ACTION_POINTER_DOWN:
        logD ("DDV Intercept P DOWN"); // logD: shell around Log.d()
        break;
      case MotionEvent.ACTION_MOVE:
        logD ("DDV Intercept MOVE");
        break;
      case MotionEvent.ACTION_UP:
        logD ("DDV Intercept UP");
        break;
      case MotionEvent.ACTION_POINTER_UP:
        logD ("DDV Intercept P UP " + ev.getActionIndex());
        break;
      case MotionEvent.ACTION_CANCEL: 
        logD ("DDV Intercept CANCEL");
        break;
      default:
        logD ("DDV Intercept " + (action & MotionEvent.ACTION_MASK));
    }        
    return false;
  }

У меня также есть код для onTouch, который возвращает false, за исключением одного случая в ACTION_MOVE; однако он вызван только для ACTION_DOWN; поэтому он возвращает только false.

Ответ 1

Это немного сложнее, чем это. Прежде всего вам нужно переопределить onTouchEvent() и обрабатывать события ACTION_DOWN и MOVE. Затем произойдет следующее.

  • Событие
  • ACTION_DOWN сначала отправляется на onInterceptTouchEvent(). Вы должны вернуть false оттуда.
  • Теперь есть два случая:
    • Если в дереве представлений нет осязаемого вида ACTION_DONW, то событие ACTION_DOWN и все последующие события отправляются на onTouchEvent(). Вы должны вернуть true оттуда. Только после этого вы будете получать последующие события, отправленные по методу onTouchEvent(). Независимо от того, вернетесь ли вы true или false, onInterceptTouchEvent() больше не будет получать никаких последующих событий.
    • Если есть осязаемое представление, все события будут отправляться на onInterceptTouchEvent() (включая ACTION_MOVE события). Вам нужно вернуть true оттуда после обнаружения вашего жеста. Как только вы вернетесь true отсюда, touchable view получит событие ACTION_CANCEL, и все последующие события будут отправлены в метод onTouchEvent().

Надеюсь, что это поможет.