2011-12-28 3 views
1

У меня есть масштабирование и перетаскивание изображения в моем приложении. Мое требование - это максимальное количество изображений и максимальный уровень масштабирования. Я использовал приведенный ниже код.Как установить максимальный и минимальный уровни масштабирования изображения в Android?

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; 

    static final float MAX_ZOOM = 5.0f; 
    static final float MIN_ZOOM = 1.0f; 

    // 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.findstation); 
     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); 
    } 
} 

Не могли бы вы рассказать мне, как установить максимальный и минимальный уровни масштабирования?

+0

изменяющегося значения '' MAX_ZOOM' и MIN_ZOOM' недостаточно? –

ответ

1

Привет вам нужно определить максимальный уровень Zooming

private static final float MIN_ZOOM = 1.0f; 
private static final float MAX_ZOOM = //set Maximum zooming level 

float scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM)); 
+0

спасибо за ваш отзыв, но выше код не работает в моем приложении. может у, пожалуйста, скажите мне, где я сделал ошибку? – NareshRavva

0

Это решение не работает, вызывает масштаб относительное значение, но MIN_ZOOM и MAX_ZOOM являются абсолютными. Я решил эту проблему так:

public class GestureImageView extends ImageView { 
private static final float MIN_DISTANCE_FOR_ZOOM = 5f; 
private static final float MAX_SCALE_RATIO = 5f; 
private static final int SCALE_X_INDEX = 0; 
private static final int MATRIX_SIZE = 9; 
private static final int NONE = 0; 
private static final int DRAG = 1; 
private static final int ZOOM = 2; 
private int mode = NONE; 
private GestureDetector gestureDetector; 
private Matrix fitScreenMatrix = new Matrix(); 
private Matrix defaultMatrix = new Matrix(); 
private Matrix matrix = new Matrix(); 
private Matrix savedMatrix = new Matrix(); 
private PointF start = new PointF(0, 0); 
private PointF mid = new PointF(0, 0); 
private float oldDist = 1f; 
private float minScale; 
private float maxScale; 


public GestureImageView(Context context) { 
    super(context); 

    gestureDetector = new GestureDetector(context, new DoubleTapListener()); 
    setOnTouchListener(new ZoomDragListener()); 
    setScaleType(AsyncGestureImageView.ScaleType.MATRIX); 
} 

private void calculateDefaultValues(Drawable drawable) { 
    float imgWidth = drawable.getIntrinsicWidth(); 
    float imgHeight = drawable.getIntrinsicHeight(); 
    float width = getWidth(); 
    float height = getHeight(); 

    float widthRatio = width/imgWidth; 
    float heightRatio = height/imgHeight; 

    float values[] = new float[MATRIX_SIZE]; 
    float ratio; 
    PointF fitScreenPosition; 
    PointF defaultPosition = new PointF((width - imgWidth)/2f, (height - imgHeight)/2f); 

    if (widthRatio < heightRatio) { 
     ratio = widthRatio; 
     fitScreenPosition = new PointF(0f, (height/ratio-imgHeight)/2f); 
    } else { 
     ratio = heightRatio; 
     fitScreenPosition = new PointF((width/ratio - imgWidth)/2f, 0f); 
    } 

    fitScreenMatrix.postTranslate(fitScreenPosition.x, fitScreenPosition.y); 
    fitScreenMatrix.postScale(ratio, ratio, 0, 0); 
    fitScreenMatrix.getValues(values); 
    defaultMatrix.postTranslate(defaultPosition.x, defaultPosition.y); 

    maxScale = values[SCALE_X_INDEX] * MAX_SCALE_RATIO; 
    minScale = values[SCALE_X_INDEX]; 
} 

private void fitScreen() { 
    matrix.set(fitScreenMatrix); 
    setImageMatrix(matrix); 
} 

private void defaultScreen() { 
    matrix.set(defaultMatrix); 
    setImageMatrix(matrix); 
} 

private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener { 
    @Override 
    public boolean onDoubleTap(MotionEvent e) { 
     if (isFitScreen()) { 
      defaultScreen(); 
      return true; 
     } 
     fitScreen(); 
     return true; 
    } 
} 

public boolean isFitScreen() { 
    return matrix.equals(fitScreenMatrix); 
} 

private class ZoomDragListener implements OnTouchListener { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     gestureDetector.onTouchEvent(event); 
     AsyncGestureImageView i = (AsyncGestureImageView) v; 
     dragAndZoom(i, event); 

     return true; 
    } 

    private void dragAndZoom(View v, MotionEvent event) { 
     AsyncGestureImageView view = (AsyncGestureImageView) v; 

     switch (event.getAction() & MotionEvent.ACTION_MASK) { 
      case MotionEvent.ACTION_DOWN: 
       savedMatrix.set(matrix); 
       start.x = event.getX(); 
       start.y = event.getY(); 
       if (isFitScreen()) { 
        return; 
       } 
       mode = DRAG; 
       break; 

      case MotionEvent.ACTION_UP: 

      case MotionEvent.ACTION_POINTER_UP: 
       mode = NONE; 
       break; 

      case MotionEvent.ACTION_POINTER_DOWN: 
       oldDist = gestureDistance(event); 
       if (oldDist > MIN_DISTANCE_FOR_ZOOM) { 
        savedMatrix.set(matrix); 
        midPoint(mid, event); 
        mode = ZOOM; 

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

        if (newDist > MIN_DISTANCE_FOR_ZOOM) { 
         matrix.set(savedMatrix); 

         float scale = newDist/oldDist; 
         float values[] = new float[MATRIX_SIZE]; 
         matrix.getValues(values); 
         float currentScale = values[SCALE_X_INDEX]; 
         float newScale = currentScale * scale; 

         if (newScale > maxScale) { 
          scale = maxScale/currentScale; 
         } 
         if (newScale < minScale) { 
          scale = minScale/currentScale; 
         } 

         matrix.postScale(scale, scale, mid.x, mid.y); 
        } 
       } 
       break; 
     } 

     view.setImageMatrix(matrix); 

    } 

    private float gestureDistance(MotionEvent event) { 
     if (event.getPointerCount() != 2) { 
      return 0; 
     } 
     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) { 
     point.x = event.getX(0)/2 + event.getX(1)/2; 
     point.y = event.getY(0)/2 + event.getY(1)/2; 
    } 
} 

@Override 
public void setImageDrawable(Drawable drawable) { 
    if (drawable != null) { 
     calculateDefaultValues(drawable); 
     fitScreen(); 
    } 
    super.setImageDrawable(drawable); 
} 
+0

Это не полная версия кода, но фьючерсы, которые вам нужны, были реализованы. – SiavA