ScaleGestureDetector не обнаруживает конец жеста

Я подключил ScaleGestureDetector к OnTouchListener, как указано в документации Android. По какой-то причине ScaleGestureDetector не всегда обнаруживает конец жеста сжатия. Чаще всего это происходит при быстром пережатии от большого к меньшему.

Эффект заключается в том, что после того, как я отпустил оба пальца, детектор не запускает событие окончания жеста. Если я коснусь экрана одним из них после этого, он все равно будет думать, что я продолжаю жест масштабирования (продолжает запускать события onScale). Мне нужно сделать еще один жест, чтобы детектор сработал в конце события.

Я добавил журналы в OnTouchListener, и когда жест масштабирования застревает, я по-прежнему обычно получаю события движения при использовании одного пальца, а event.getPointerCount() равно 1.

Я удостоверился, что у меня нет никаких других слушателей, вмешивающихся. Представление с onTouchListener — не единственное представление на экране, но этот эффект возникает и тогда, когда я очень осторожно начинаю и заканчиваю жест внутри этого представления.

Есть ли способ улучшить обнаружение конца?

Или, если я могу вручную настроить ScaleGestureDetector на запуск onScaleEnd и изменить scaleGestureDetector.isInProgress() на false?


person Juhani    schedule 31.10.2010    source источник
comment
Как вы решили эту проблему? Комментарий Akos Cz связан с неправильными вычислениями в исходном коде, а не с причиной, по которой onScaleEnd не отправляется?   -  person vivek.m    schedule 02.08.2011
comment
@vivek.m Смотрите мой ответ ниже.   -  person Nathan Moos    schedule 31.08.2011


Ответы (2)


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

if (m_dualFingerGestureDetector.isInProgress() && (evt1.getPointerCount() == 2 || evt2.getPointerCount == 2)
{
    return false;
}
...

Мои переменные следующие:

m_dualFingerGestureDetector — это мои ScaleGestureDetector
evt1, а evt2 — это MotionEvents для жеста перетаскивания. Если у вас есть только одно событие, вы можете сократить приведенный выше код:

if (m_dualFingerGestureDetector.isInProgress() && evt.getPointerCount() == 2)
{
    return false;
}
...

Это позволяет создавать очень удобные пользовательские интерфейсы. Я всегда рекомендую использовать комбинацию детекторов жестов, чтобы добавить в ваше приложение функции панорамирования и масштабирования.

person Nathan Moos    schedule 13.08.2011

Возможно, вы столкнулись со следующей ошибкой: http://code.google.com/p/android/issues/detail?id=10067

Мне пришлось скопировать реализацию ScaleGestureDetector в мой локальный проект, чтобы применить исправление. Я также нацелен на устройства 2.1, поэтому этот класс в противном случае недоступен для меня, если я не скопирую его в свой проект.

https://android.googlesource.com/platform/frameworks/base/+/gingerbread-release/core/java/android/view/ScaleGestureDetector.java

person Akos Cz    schedule 04.11.2010
comment
Большое спасибо за ответ. Я посмотрю на это. Вполне может быть этот баг. - person Juhani; 04.11.2010
comment
Еще немного потестировав, стало ясно, что это на самом деле одна из ключевых проблем. Производительность была большой проблемой, но проблема не была полностью решена до того, как мы внедрили изменение из этого отчета об ошибке. - person Juhani; 05.11.2010