Использовать ScaleGestureDetector с GestureDetector?
В моем приложении для Android у меня есть ImageView
где я хотел бы, чтобы пользователь мог перебрасывать его влево / вправо / вверх / вниз, чтобы изменить изображение (статические карты) на соседнее. Но кроме того, я хотел бы иметь возможности масштабирования и саму карту.
Я могу заставить или бросать ИЛИ щепотку масштабирования, чтобы работать, но не вместе. я использую GestureDetector
(с SimpleOnGestureListener
) для кидания А я пользуюсь ScaleGestureDetector
(от осмысления мультитача) для масштабирования.
Сложность состоит в том, чтобы определить, какой жест слушатель будет вызывать при касании. Это не проблема кодирования, а проблема логики. При касании одним пальцем это бросок или масштаб? Даже при использовании пинч-зума начальный MotionEvent
ACTION_DOWN. Я пытался использовать размер изображения (внутренний или масштабированный?) В качестве точки решения. Но первоначальная операция масштабирования (когда размер изображения является внутренним, и я хочу увеличить его) с ACTION_DOWN, кажется, ускользает от меня.
Кто-нибудь успешно справлялся с этим ранее?
3 ответа
Вы можете передавать события обоим детекторам жестов.
Проверьте http://developer.android.com/training/gestures/scale.html разделе "Более сложный пример масштабирования":
public boolean onTouchEvent(MotionEvent event) {
boolean retVal = mScaleGestureDetector.onTouchEvent(event);
retVal = mGestureDetector.onTouchEvent(event) || retVal;
return retVal || super.onTouchEvent(event);
}
Конечно, учитывая ошибку, на которую ссылается Ratatat, super.onTouchEvent никогда не будет вызываться в приведенном выше примере, что может или не может быть хорошо, в зависимости от вашего варианта использования.
Идея ответа Рататата в порядке, но мы все равно должны передавать события в gestDetector, даже если мы не хотим прокручивать его, иначе он будет испорчен.
Я закончил с чем-то вроде этого:
scaleDetector = new ScaleGestureDetector( ... );
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (scaleDetector.isInProgress()) {
// don't allow scrolling while scaling
return false;
}
// handle scrolling
return true;
}
}
А потом onTouchEvent
Реализация должна быть как в ответе Aij:
boolean result = scaleDetector.onTouchEvent(event);
result = gestureDetector.onTouchEvent(event) || result;
return result || super.onTouchEvent(event);
Наконец-то нашел ответ по ссылке: http://code.google.com/p/android/issues/detail?id=42591
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = mScaleGestureDetector.onTouchEvent(event);
// result is always true here, so I need another way to check for a detected scaling gesture
boolean isScaling = result = mScaleGestureDetector.isInProgress();
if (!isScaling) {
// if no scaling is performed check for other gestures (fling, long tab, etc.)
result = mCommonGestureDetector.onTouchEvent(event);
}
// some irrelevant checks...
return result ? result : super.onTouchEvent(event);
}