He estado atascado en este problema durante ocho horas, así que pensé que era hora de obtener ayuda.Lienzo pellizcar-Zoom a punto dentro de los límites
Antes de comenzar mi problema, solo dejaré saber que he visitado este sitio y Google, y ninguna de las respuestas que he encontrado me ha ayudado. (This es uno, another y another.)
Este es el trato: Tengo una clase que se extiende SurfaceView
(vamos a llamarlo MySurface
) y anula muchos métodos en ella. Normalmente, dibuja varios cuadrados y cuadros de texto, lo cual está bien. Tan pronto como un usuario comienza a tocar, se convierte en Bitmap
, luego dibuja cada cuadro hasta que el usuario lo suelte.
Aquí está el problema: quiero implementar una funcionalidad tal que el usuario pueda colocar dos dedos en la pantalla, pellizcar para hacer zoom, y también para desplazarse (pero SOLAMENTE con dos dedos hacia abajo).
me encontré con un par de implementaciones de pellizcar para hacer zoom y ellas adaptada a mi objeto Canvas
en MySurface
a través de lo siguiente:
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;
}
Si bien ambos elementos funcionan bien - el desplazamiento de ida y vuelta y el pellizco -to-zoom: hay un gran problema. La función de pellizcar para hacer zoom, cuando se utiliza, se acerca al punto 0,0
, en lugar de acercarse al punto del dedo.
He intentado muchas maneras de solucionar este problema:
- Usando
canvas.scale(mScaleVector.z, mScaleVector.z, mScaleVector.x, mScaleVector.y);
; obviamente, esto produce resultados no deseados ya que los valoresmScaleVector
xey son 0-offsets. - Gestionando una coordenada "pivote" que usa la misma compensación que el método
translate()
, pero esto produce el mismo problema0,0
, o salta cuando se toca la vista. - Numerosas otras cosas ... He hecho mucho con la coordenada de pivote antes mencionada, tratando de basar su ubicación en el primer toque del usuario, y moviéndolo en relación con ese toque cada gesto sucesivo.
Además, este lienzo debe estar delimitado, por lo que el usuario no puede desplazarse para siempre. Sin embargo, cuando uso el método .scale(sx, sy, px, py)
, empuja las cosas más allá de los límites establecidos en .translate()
.
Estoy ... bastante abierto a cualquier cosa en este momento. Sé que esta funcionalidad se puede agregar, como se ve en la galería de Android 4.0 (cuando se ve una sola imagen). Intenté rastrear el código fuente que maneja esto, en vano.
Personalmente, manejo las dos posiciones de los dedos directamente usando 'onTouchEvent'. Con esto, puede encontrar fácilmente el punto medio y la escala requerida. – Doomsknight
puede por favor publicar la solución si ha resuelto el problema que estoy enfrentando el mismo problema, y mi cliente es .... :(, o puede decirme cómo ha resuelto el problema. Gracias – AkashG