Android Pinch and Zoom Image in action

I have a ListView with a set of images. When you click on any of them, the clicked image will be displayed in the new action and in the center of activity in ImageView, as well as Zoomable. The problem is that I am enlarging the image obtained by Zoom, but it also moves like drag and drop. I have to eliminate this image movement and should only be scalable from the center of the action.

ZoomInZoomOutActivity.java

public class ZoomInZoomOutActivity extends Activity implements OnTouchListener { private static final String TAG = "Touch"; @SuppressWarnings("unused") private static final float MIN_ZOOM = 1f,MAX_ZOOM = 1f; 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.imagedisp); Bundle extras = getIntent().getExtras(); long id =extras.getLong("ID"); String s=String.valueOf(id); ImageView view; view = (ImageView) findViewById(R.id.imageView1); view.setOnTouchListener(this); if (s.equals("0")) { view.setImageResource(R.drawable.img1); } else if (s.equals("1")) { view.setImageResource(R.drawable.img2); } else if (s.equals("2")) { view.setImageResource(R.drawable.img3); } else { view.setImageResource(R.drawable.img4); } } public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; view.setScaleType(ImageView.ScaleType.MATRIX); float scale; 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_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; Log.d(TAG, "mode=NONE"); break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); Log.d(TAG, "oldDist=" + oldDist); if (oldDist > 5f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; Log.d(TAG, "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 = spacing(event); Log.d(TAG, "newDist=" + newDist); if (newDist > 5f) { matrix.set(savedMatrix); scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } } break; } view.setImageMatrix(matrix); return true; } 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); } } 

imagedisp.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <ImageView android:layout_width="fill_parent" android:id="@+id/imageView1" android:src="@drawable/img1" android:layout_height="fill_parent" android:scaleType="centerInside"> </ImageView> </LinearLayout> 
+5
android android-listview android-imageview pinchzoom
source share
1 answer

Try this code:

 import android.content.Context; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.PointF; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; import android.widget.ImageView; /** * Extends Android ImageView to include pinch zooming and panning. */ public class TouchImageView extends ImageView { Matrix matrix = 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 last = new PointF(); PointF start = new PointF(); float minScale = 1f; float maxScale = 3f; float[] m; float redundantXSpace, redundantYSpace; float width, height; static final int CLICK = 3; float saveScale = 1f; float right, bottom, origWidth, origHeight, bmWidth, bmHeight; ScaleGestureDetector mScaleDetector; Context context; public TouchImageView(Context context) { super(context); sharedConstructing(context); } public TouchImageView(Context context, AttributeSet attrs) { super(context, attrs); sharedConstructing(context); } private void sharedConstructing(Context context) { super.setClickable(true); this.context = context; mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); matrix.setTranslate(1f, 1f); m = new float[9]; setImageMatrix(matrix); setScaleType(ScaleType.MATRIX); setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { mScaleDetector.onTouchEvent(event); matrix.getValues(m); float x = m[Matrix.MTRANS_X]; float y = m[Matrix.MTRANS_Y]; PointF curr = new PointF(event.getX(), event.getY()); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: last.set(event.getX(), event.getY()); start.set(last); mode = DRAG; break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { float deltaX = curr.x - last.x; float deltaY = curr.y - last.y; float scaleWidth = Math.round(origWidth * saveScale); float scaleHeight = Math.round(origHeight * saveScale); if (scaleWidth < width) { deltaX = 0; if (y + deltaY > 0) deltaY = -y; else if (y + deltaY < -bottom) deltaY = -(y + bottom); } else if (scaleHeight < height) { deltaY = 0; if (x + deltaX > 0) deltaX = -x; else if (x + deltaX < -right) deltaX = -(x + right); } else { if (x + deltaX > 0) deltaX = -x; else if (x + deltaX < -right) deltaX = -(x + right); if (y + deltaY > 0) deltaY = -y; else if (y + deltaY < -bottom) deltaY = -(y + bottom); } matrix.postTranslate(deltaX, deltaY); last.set(curr.x, curr.y); } break; case MotionEvent.ACTION_UP: mode = NONE; int xDiff = (int) Math.abs(curr.x - start.x); int yDiff = (int) Math.abs(curr.y - start.y); if (xDiff < CLICK && yDiff < CLICK) performClick(); break; case MotionEvent.ACTION_POINTER_UP: mode = NONE; break; } setImageMatrix(matrix); invalidate(); return true; // indicate event was handled } }); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); if (bm != null) { bmWidth = bm.getWidth(); bmHeight = bm.getHeight(); } } public void setMaxZoom(float x) { maxScale = x; } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScaleBegin(ScaleGestureDetector detector) { mode = ZOOM; return true; } @Override public boolean onScale(ScaleGestureDetector detector) { float mScaleFactor = (float) Math.min( Math.max(.95f, detector.getScaleFactor()), 1.05); float origScale = saveScale; saveScale *= mScaleFactor; if (saveScale > maxScale) { saveScale = maxScale; mScaleFactor = maxScale / origScale; } else if (saveScale < minScale) { saveScale = minScale; mScaleFactor = minScale / origScale; } right = width * saveScale - width - (2 * redundantXSpace * saveScale); bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); if (origWidth * saveScale <= width || origHeight * saveScale <= height) { matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2); if (mScaleFactor < 1) { matrix.getValues(m); float x = m[Matrix.MTRANS_X]; float y = m[Matrix.MTRANS_Y]; if (mScaleFactor < 1) { if (Math.round(origWidth * saveScale) < width) { if (y < -bottom) matrix.postTranslate(0, -(y + bottom)); else if (y > 0) matrix.postTranslate(0, -y); } else { if (x < -right) matrix.postTranslate(-(x + right), 0); else if (x > 0) matrix.postTranslate(-x, 0); } } } } else { matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); matrix.getValues(m); float x = m[Matrix.MTRANS_X]; float y = m[Matrix.MTRANS_Y]; if (mScaleFactor < 1) { if (x < -right) matrix.postTranslate(-(x + right), 0); else if (x > 0) matrix.postTranslate(-x, 0); if (y < -bottom) matrix.postTranslate(0, -(y + bottom)); else if (y > 0) matrix.postTranslate(0, -y); } } return true; } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = MeasureSpec.getSize(widthMeasureSpec); height = MeasureSpec.getSize(heightMeasureSpec); // Fit to screen. float scale; float scaleX = (float) width / (float) bmWidth; float scaleY = (float) height / (float) bmHeight; scale = Math.min(scaleX, scaleY); matrix.setScale(scale, scale); setImageMatrix(matrix); saveScale = 1f; // Center the image redundantYSpace = (float) height - (scale * (float) bmHeight); redundantXSpace = (float) width - (scale * (float) bmWidth); redundantYSpace /= (float) 2; redundantXSpace /= (float) 2; matrix.postTranslate(redundantXSpace, redundantYSpace); origWidth = width - 2 * redundantXSpace; origHeight = height - 2 * redundantYSpace; right = width * saveScale - width - (2 * redundantXSpace * saveScale); bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); setImageMatrix(matrix); } } 
+9
source share

All Articles