Может ли один объект OnGestureListener иметь дело с двумя объектами GestureDetector? - PullRequest
1 голос
/ 06 июля 2011

Я создаю представление, которое должно потреблять практически любые жесты. Для этого я создал ScaleGestureDetector и GestureDetector. Я также создал один класс слушателя и понял, что мог бы реализовать каждый интерфейс, который мне нужен; так я и сделал. Это имеет смысл для OnGestureListener и OnDoubleTapListener, потому что они принадлежат одному классу, но:

  • Ожидает ли ScaleGestureDetector свой собственный класс слушателей?
  • Если он доволен тем же классом, будет ли он ожидать своего собственного объекта?
  • И наоборот, НУЖНО ли я использовать один и тот же слушатель с обоими детекторами?

Эксперимент подтвердил следующее:

  • Вы действительно можете использовать один класс слушателя, но
  • ScaleGestureDetector и GestureDetector могут раздражать друг друга, если они потребляют одно и то же событие. Тем не менее
  • Похоже, что вы можете предотвратить это взаимное раздражение, всегда вызывая детектор масштаба FIRST, а затем проверяя его метод isInProgress () перед запуском обычного детектора:

    public boolean onTouchEvent(MotionEvent event) {
    //let the ScaleGestureDetector try first
        mScaleDetector.onTouchEvent(event);
    //if isInProgress() returns true then it's consuming the event
        if(mScaleDetector.isInProgress()) return true;
    //if isInProgress() returns false it isn't consuming the event
    //it's therefore safe to pass it to the regular detector
        mPrimaryDetector.onTouchEvent(event);
        return true;
    }
    

Ответы [ 3 ]

3 голосов
/ 29 мая 2013

Чтобы определить, является ли MotionEvent событием мультитач, просто используйте MotionEvent.getPointerCount() > 1.Поэтому я думаю, что следующий код будет хорошо работать:

public boolean onTouchEvent(MotionEvent event) {
    if (event.getPointerCount() > 1) {
        mScaleDetector.onTouchEvent(event);
    } else {
        mDetector.onTouchEvent(event);
    }
    return true;
}
2 голосов
/ 04 января 2012

ScaleGestureDetector и GestureDetector могут раздражать друг друга, если они используют одно и то же событие.Однако кажется, что вы можете предотвратить это взаимное раздражение, всегда вызывая детектор весов FIRST, а затем проверяя его метод isInProgress () перед запуском обычного детектора

Лично я не нашел никаких проблем, позволив им обоимобрабатывать одно и то же событие касания.

Андроид GestureDetector имеет конструктор , который принимает логическое значение ignoreMultiTouch.Если для ignoreMultiTouch установлено значение true, обработка событий прикосновения GestureDetector будет игнорировать любые события касания.(Android фактически устанавливает ignoreMultiTouch на true, если целевой уровень API>> Froyo, поэтому вам, вероятно, не нужно будет явно устанавливать его.)

Если вы вызываете только mPrimaryDetector.onTouchEvent(event), когда mScaleDetector.isInProgress() возвращает false, вы неправильно получите длинное событие нажатия.Причина в том, что GestureDetector имеет следующий код в onTouchEvent(MotionEvent ev), чтобы гарантировать, что он не конфликтует с мультитач-жестами:

case MotionEvent.ACTION_POINTER_DOWN:
  if (mIgnoreMultitouch) {
    // Multitouch event - abort.
    cancel();
  }
  break;

cancel() сделает то, что говорит, и отменит любые жесты одним касанием.(Если вам действительно любопытно, вы можете взглянуть на этот код GestureDetector самостоятельно; на самом деле он использует обработчик для отправки / удаления сообщений).

Надеюсь, это поможет всем, у кого возникли такие же проблемыЯ был.

0 голосов
/ 01 февраля 2012

Это прекрасно работает для меня:

@Override
public boolean onTouchEvent(MotionEvent event) {
    m_sGestureDetector.onTouchEvent(event);
    m_GestureDetector.onTouchEvent(event);
    return true;
}
...