2011-03-21 12 views
5

Hola, estoy tratando de crear una aplicación en la que pueda hacer zoom y desplazarse por el mapa de un sitio de campus. Lo tengo funcionando, pero me he encontrado con problemas para restringir la cantidad de panoramización y zoom. Necesito ayuda para establecer los límites de acercamiento y acercamiento.
Cualquier ayuda sería muy apreciada,Restricción de panorámica y acercamiento

Gracias de antemano
Aquí está el código.

package com.scott; 

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.OnClickListener; 
import android.view.View.OnTouchListener; 
import android.widget.Button; 
import android.widget.ImageView; 

public class Touch extends Activity implements OnTouchListener,OnClickListener { 
    private static final String TAG = "Touch"; 

    Matrix matrix = new Matrix(); 
    Matrix savedMatrix = new Matrix(); 
    static final int NONE = 0; 
    static final int DRAG = 1; 
    static final int ZOOM = 2; 
    int mode = NONE; 

    PointF start = new PointF(); 
    PointF mid = new PointF(); 
    float oldDist = 1f; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.touch); 
     ImageView view = (ImageView) findViewById(R.id.imageView); 
     view.setOnTouchListener(this); 

    Button buttonClose =(Button)findViewById(R.id.buttonClose); 
    buttonClose.setOnClickListener(this); 

    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     ImageView view = (ImageView) v; 


     dumpEvent(event); 

     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; 
    } 

    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()); 
    } 

    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); 
    } 

    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); 
    } 

@Override 
public void onClick(View src) { 
    switch(src.getId()){ 
    case R.id.buttonClose: 
     finish(); 
     break; 

    } 
    } 
} 

Respuesta

5

bien que probablemente se podría usar esto para ajustar con postTranslate, este método debe ser llamado después estás poseen postScale y postTranslate

private void adjustPan(){ 
     float[] matrixValues = new float[9]; 
     matrix.getValues(matrixValues); 
     float currentY = matrixValues[Matrix.MTRANS_Y]; 
     float currentX = matrixValues[Matrix.MTRANS_X]; 
     float currentScale = matrixValues[Matrix.MSCALE_X]; 
     float currentHeight = bitmap.getHeight() * currentScale; 
     float currentWidth = bitmap.getWidth() * currentScale; 
     float newX = currentX; 
     float newY = currentY; 

     RectF drawingRect = new RectF(newX, newY, newX + currentWidth, 
         newY + currentHeight); 
     float diffUp = Math.min(displayRect.bottom - drawingRect.bottom, 
         displayRect.top - drawingRect.top); 
     float diffDown = Math.max(displayRect.bottom - drawingRect.bottom, 
         displayRect.top - drawingRect.top); 
     float diffLeft = Math.min(displayRect.left - drawingRect.left, 
         displayRect.right - drawingRect.right); 
     float diffRight = Math.max(displayRect.left - drawingRect.left, 
         displayRect.right - drawingRect.right); 

     float x = 0, y = 0; 

     if (diffUp > 0) 
       y += diffUp; 
     if (diffDown < 0) 
       y += diffDown; 
     if (diffLeft > 0) 
       x += diffLeft; 
     if (diffRight < 0) 
       x += diffRight; 

     if(currentWidth < displayRect.width()) 
       x = -currentX + (displayRect.width() - currentWidth)/2; 
     if(currentHeight<displayRect.height()) 
       y = -currentY + (displayRect.height() - currentHeight)/2; 

     matrix.postTranslate(x, y); 
} 

donde displayRect es un RectF que debe ser algo como esto:

  displayRect = new RectF(); 
    displayRect.set(0, 0, displaywidth, displayheight); 

en cuanto a usted es mínima y máxima de zoom que se necesita algo como esto antes estás postScale:

   float[] f = new float[9]; 
     matrix.getValues(f); 
     float currentScale = f[Matrix.MSCALE_X]; 

     if (scale * currentScale > maxZoom) 
       scale = maxZoom/currentScale; 
      else if (scale * currentScale < minZoom) 
       scale = minZoom/currentScale; 

donde minZoom es:

minZoom = Math.min(displayRect.width()/bitmap.getWidth(), displayRect.height()/bitmap.getHeight()); 

y MaxZoom es lo que te gusta que sea.

Espero que esto haya sido útil.

(original tomada de algún sitio, no puede encontrar enlace ahora aunque)

+1

Esto tal vez es el enlace: http://code.google.com/p/ametro/source/browse/trunk/workspace/aMetro /src/org/ametro/multitouch/MultiTouchController.java?r=436 – daveomcd

Cuestiones relacionadas