Here is the full code for zooming and panning (Touch.java with some changes that can be used in practice)
public class Touch implements OnTouchListener { // These matrices will be used to move and zoom image public static Matrix matrix = new Matrix(); public static 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; private static final float MAX_ZOOM = (float) 3; private static final float MIN_ZOOM = 1; int mode = NONE; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; int width,height; @Override public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; Rect bounds = view.getDrawable().getBounds(); width = bounds.right - bounds.left; height = bounds.bottom - bounds.top; // 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()); mode = DRAG; break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: 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); if (newDist > 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } } break; } //---------------------------------------------------- limitZoom(matrix); limitDrag( matrix); //---------------------------------------------------- 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("]"); } /** 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); } private void limitZoom(Matrix m) { float[] values = new float[9]; m.getValues(values); float scaleX = values[Matrix.MSCALE_X]; float scaleY = values[Matrix.MSCALE_Y]; if(scaleX > MAX_ZOOM) { scaleX = MAX_ZOOM; } else if(scaleX < MIN_ZOOM) { scaleX = MIN_ZOOM; } if(scaleY > MAX_ZOOM) { scaleY = MAX_ZOOM; } else if(scaleY < MIN_ZOOM) { scaleY = MIN_ZOOM; } values[Matrix.MSCALE_X] = scaleX; values[Matrix.MSCALE_Y] = scaleY; m.setValues(values); } private void limitDrag(Matrix m) { float[] values = new float[9]; m.getValues(values); float transX = values[Matrix.MTRANS_X]; float transY = values[Matrix.MTRANS_Y]; float scaleX = values[Matrix.MSCALE_X]; float scaleY = values[Matrix.MSCALE_Y]; //--- limit moving to left --- float minX = (-width + 0) * (scaleX-1); float minY = (-height + 0) * (scaleY-1); //--- limit moving to right --- float maxX=minX+width*(scaleX-1); float maxY=minY+height*(scaleY-1); if(transX>maxX){transX = maxX;} if(transX<minX){transX = minX;} if(transY>maxY){transY = maxY;} if(transY<minY){transY = minY;} values[Matrix.MTRANS_X] = transX; values[Matrix.MTRANS_Y] = transY; m.setValues(values); } }
Vivek Hirpara 03 Oct '17 at 5:25 2017-10-03 05:25
source share