Zoom y arrastrar imágenes usando matriz en android
Conseguí el código siguiente (de hola androide por Ed Burnette) que trabajaba agradable y puedo arrastrar y hacer zoom para una imagen.
import android.app.Activity; import android.graphics.Matrix; import android.graphics.PointF; import android.os.Bundle; import android.util.FloatMath; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; public class Touch extends Activity implements OnTouchListener { private static final String TAG = "Touch"; // These matrices will be used to move and zoom image Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); // We can be in one of these 3 states static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ImageView view = (ImageView) findViewById(R.id.imageView); view.setOnTouchListener(this); } @Override public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; // Dump touch event to log dumpEvent(event); // Handle touch events here... switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: savedMatrix.set(matrix); start.set(event.getX(), event.getY()); Log.d(TAG, "mode=DRAG"); mode = DRAG; break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); Log.d(TAG, "oldDist=" + oldDist); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; Log.d(TAG, "mode=ZOOM"); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; Log.d(TAG, "mode=NONE"); break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { // ... matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } else if (mode == ZOOM) { float newDist = spacing(event); Log.d(TAG, "newDist=" + newDist); if (newDist > 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } } break; } view.setImageMatrix(matrix); return true; // indicate event was handled } /** Show an event in the LogCat view, for debugging */ private void dumpEvent(MotionEvent event) { String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; StringBuilder sb = new StringBuilder(); int action = event.getAction(); int actionCode = action & MotionEvent.ACTION_MASK; sb.append("event ACTION_").append(names[actionCode]); if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) { sb.append("(pid ").append( action >> MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append(")"); } sb.append("["); for (int i = 0; i < event.getPointerCount(); i++) { sb.append("#").append(i); sb.append("(pid ").append(event.getPointerId(i)); sb.append(")=").append((int) event.getX(i)); sb.append(",").append((int) event.getY(i)); if (i + 1 < event.getPointerCount()) sb.append(";"); } sb.append("]"); Log.d(TAG, sb.toString()); } /** Determine the space between the first two fingers */ private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } /** Calculate the mid point of the first two fingers */ private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } }
Sin embargo, ¿puede alguien explicar amablemente claramente las funciones de las siguientes 5 líneas dentro del código anterior?
- Obtener el nivel de zoom de mapa para determinados límites en Android como en JS API de Google Maps: map.getBoundsZoomLevel (límites)
- Construcción de un contenedor capaz de hacer zoom
- Establecer el nivel de zoom mínimo para MapView
- Android google maps no se puede ampliar con compás activo
- Android ViewGroup.setScaleX () hace que la vista se recorte
savedMatrix.set(matrix); matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x,event.getY() - start.y); float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y);
Gracias de antemano por la explicación 🙂
- Obtenga coordenadas del centro de la página web en dispositivos de tableta mediante JavaScript
- ¿La mejor manera de tener una superposición de zoom y pan en Android?
- Lona de Android, múltiples rutas con diferentes cantidades de zoom
- Cómo capturar el final de una animación Zoom In / Out de un MapController?
- ¿Cómo obtener el valor de zoom de la matriz arbitraria?
- Obtener el ancho interno de la ventana y la altura del androide integrado en el navegador web en todos los niveles de zoom
- Dos dedos o pinc zoom a mapview en osmdroid
- ¿Cómo realizar zoom in / out en VideoView en android?
savedMatrix.set(matrix);
Copiando el contenido de "matriz" en "savedMatrix"
matrix.postTranslate(event.getX() - start.x,event.getY() - start.y);
"Matrix" determina alguna transformación, como el zoom y el movimiento. "PostTranslate" agrega la transformación "move" a la transformación ya definida en "matrix". Es decir, "matriz" contiene alguna transformación de zoom, y luego después de aplicar postTranslate determinará la transformación "zoom y luego mover".
float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y);
Adición de transformación de zoom con centro en (mid.x, mid.y) a la transformación ya definida en "matrix"
Para una solución alternativa, he utilizado un ejemplo del blog de desarrollo de Android. http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
La razón principal por la que utilicé este ejemplo en lugar del que implementaste es que escribieron una versión modificada del artículo del blog. En este artículo se presenta cómo administrar eventos multitáctiles en dispositivos que no tienen instalado Android 2.2 o superior. http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html
- Publicar en Google Play a través de la línea de comandos
- Android – Geocoder.getFromLocationName () no funciona en el dispositivo ICS