Я застрял на этой проблеме в течение восьми часов, поэтому я решил, что пришло время получить помощь.
Прежде чем я начну свою проблему, я просто сообщу, что я просмотрел этот сайт и Google, и ни один из ответов, которые я нашел, не помог.(Это одно, другое , а другое .)
Вот в чем дело :У меня есть класс, который расширяетсяSurfaceView
(назовем этоMySurface
)и переопределяет многие методы в нем. Обычно он рисует несколько квадратов и текстовых полей, и это нормально. Как только пользователь начинает касаться, он преобразуется в Bitmap
, а затем рисует каждый кадр до тех пор, пока пользователь не отпустит.
Вот в чем загвоздка :Я хочу реализовать такую функциональность, чтобы пользователь мог прикоснуться к экрану двумя пальцами, сводить для масштабирования,а также панорамировать (, но ТОЛЬКО двумя пальцами вниз ).
Я нашел несколько реализаций масштабирования от -до -и адаптировал их к моему объекту Canvas
в MySurface
с помощью следующего:
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(mScaleVector.z, mScaleVector.z); // This is the scale factor as seen below
canvas.translate(mScaleVector.x, mScaleVector.y); // These are offset values from 0,0, both working fine
// Start draw code
//...
// End draw code
canvas.restore();
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float factor = detector.getScaleFactor();
if (Math.abs(factor - 1.0f) >= 0.0075f) {
mScaleVector.z *= factor;
mScaleVector.z = Math.max(MIN_ZOOM, Math.min(mScaleVector.z, MAX_ZOOM));
}
//...
invalidate();
return true;
}
}
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
if (event.getPointerCount() == 2) {
if (action == MotionEvent.ACTION_POINTER_DOWN && pointerIndex == 1) {
// The various pivot coordinate codes would belong here
}
}
detector.onTouchEvent(event); // Calls the Scale Gesture Detector
return true;
}
В то время как оба элемента работают нормально --прокрутка вперед и назад и масштабирование -до -масштабирование --, есть одна большая проблема. Масштабирование щипком от -до -при использовании увеличивает масштаб до точки 0,0
вместо увеличения точки пальца.
Я пробовал много способов исправить это:
canvas.scale(mScaleVector.z, mScaleVector.z, mScaleVector.x, mScaleVector.y);
; очевидно, это приводит к нежелательным результатам, поскольку значения mScaleVector
x и y равны 0 -смещениям.translate()
, но вызывает либо ту же проблему 0,0
, либо скачки при касании представления.Кроме того, этот холст должен быть ограничен, чтобы пользователь не мог прокручивать его вечно. Однако, когда я использую метод .scale(sx, sy, px, py)
, он выходит за все границы, которые я установил в .translate()
.
Я... в значительной степени открыта ко всему на данный момент. Я знаю, что эту функцию можно добавить, так как она видна в галерее Android 4.0 (при просмотре одного изображения ). Я пытался отследить исходный код, который обрабатывает это, но безрезультатно.