2011-05-04 9 views
11

obtuve el siguiente código (de Hello android por Ed Burnette) que funciona muy bien y soy capaz de arrastrar y hacer zoom para una imagen.zoom y arrastrando imágenes usando la matriz en Android

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 las funciones de las siguientes 5 líneas dentro del código anterior?

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 :)

+1

Es posible que debas agregar 'imgView.setScaleType (ScaleType.MATRIX);' para usar este código – ethrbunny

+0

¿Dónde puedo encontrar el código completo? – eyal

+0

Este código parece funcionar bien, me refiero a que puedo ver todos los mensajes de Logcat sobre movimiento, arrastre, etc., pero mi ImageView no se mueve en la pantalla, ni zoom, cosa cableada, ¿cuál puede ser el problema? – cubycode

Respuesta

6
savedMatrix.set(matrix); 

copia de "matriz" contenido en "savedMatrix"

matrix.postTranslate(event.getX() - start.x,event.getY() - start.y); 

"matriz" determina alguna transformación, como el zoom y moverse. "postTranslate" agrega la transformación de "movimiento" a la transformación ya definida en "matriz". Es decir. "matriz" contiene alguna transformación de zoom, y luego de aplicar postTranslate determinará la transformación de "acercar y luego mover".

float scale = newDist/oldDist; 
matrix.postScale(scale, scale, mid.x, mid.y); 

Adición de transformación zoom con centro en (mid.x, mid.y) a la transformación ya definido en "matriz"

1

Para una solución alternativa, que utiliza un ejemplo del blog dev 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 implementó es que escribieron una versión modificada del artículo del blog. Este artículo presenta cómo manejar eventos multitouch 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

+0

gracias el enlace es útil –

Cuestiones relacionadas