Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid Image View Pinch Zooming
    text
    copied!<p>I am using code sample from <a href="http://android-developers.blogspot.in/2010/06/making-sense-of-multitouch.html" rel="noreferrer">Making Sense of Multitouch</a> for zooming image view. On ScaleListener I added <code>ScaleGestureDetector.getFocusX() and getFocusY()</code>for content to zoom about the focal point of the gesture. It is working fine. </p> <p><strong><em>The problem is, on first multitouch the entire Image drawing position is changing to the current touch point and zooming it from there. Could you help me to resolve this issue?</em></strong></p> <p>Here is My Code Sample For TouchImageView.</p> <pre><code>public class TouchImageViewSample extends ImageView { private Paint borderPaint = null; private Paint backgroundPaint = null; private float mPosX = 0f; private float mPosY = 0f; private float mLastTouchX; private float mLastTouchY; private static final int INVALID_POINTER_ID = -1; private static final String LOG_TAG = "TouchImageView"; // The ‘active pointer’ is the one currently moving our object. private int mActivePointerId = INVALID_POINTER_ID; public TouchImageViewSample(Context context) { this(context, null, 0); } public TouchImageViewSample(Context context, AttributeSet attrs) { this(context, attrs, 0); } private ScaleGestureDetector mScaleDetector; private float mScaleFactor = 1.f; // Existing code ... public TouchImageViewSample(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // Create our ScaleGestureDetector mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); borderPaint = new Paint(); borderPaint.setARGB(255, 255, 128, 0); borderPaint.setStyle(Paint.Style.STROKE); borderPaint.setStrokeWidth(4); backgroundPaint = new Paint(); backgroundPaint.setARGB(32, 255, 255, 255); backgroundPaint.setStyle(Paint.Style.FILL); } @Override public boolean onTouchEvent(MotionEvent ev) { // Let the ScaleGestureDetector inspect all events. mScaleDetector.onTouchEvent(ev); final int action = ev.getAction(); switch (action &amp; MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); mLastTouchX = x; mLastTouchY = y; mActivePointerId = ev.getPointerId(0); break; } case MotionEvent.ACTION_MOVE: { final int pointerIndex = ev.findPointerIndex(mActivePointerId); final float x = ev.getX(pointerIndex); final float y = ev.getY(pointerIndex); // Only move if the ScaleGestureDetector isn't processing a gesture. if (!mScaleDetector.isInProgress()) { final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; mPosX += dx; mPosY += dy; invalidate(); } mLastTouchX = x; mLastTouchY = y; break; } case MotionEvent.ACTION_UP: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_CANCEL: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_POINTER_UP: { final int pointerIndex = (ev.getAction() &amp; MotionEvent.ACTION_POINTER_INDEX_MASK) &gt;&gt; MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = ev.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { // This was our active pointer going up. Choose a new // active pointer and adjust accordingly. final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = ev.getX(newPointerIndex); mLastTouchY = ev.getY(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); } break; } } return true; } /* * (non-Javadoc) * * @see android.view.View#draw(android.graphics.Canvas) */ @Override public void draw(Canvas canvas) { super.draw(canvas); canvas.drawRect(0, 0, getWidth() - 1, getHeight() - 1, borderPaint); } @Override public void onDraw(Canvas canvas) { canvas.drawRect(0, 0, getWidth() - 1, getHeight() - 1, backgroundPaint); if (this.getDrawable() != null) { canvas.save(); canvas.translate(mPosX, mPosY); Matrix matrix = new Matrix(); matrix.postScale(mScaleFactor, mScaleFactor, pivotPointX, pivotPointY); // canvas.setMatrix(matrix); canvas.drawBitmap( ((BitmapDrawable) this.getDrawable()).getBitmap(), matrix, null); // this.getDrawable().draw(canvas); canvas.restore(); } } /* * (non-Javadoc) * * @see * android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable * ) */ @Override public void setImageDrawable(Drawable drawable) { // Constrain to given size but keep aspect ratio int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); mLastTouchX = mPosX = 0; mLastTouchY = mPosY = 0; int borderWidth = (int) borderPaint.getStrokeWidth(); mScaleFactor = Math.min(((float) getLayoutParams().width - borderWidth) / width, ((float) getLayoutParams().height - borderWidth) / height); pivotPointX = (((float) getLayoutParams().width - borderWidth) - (int) (width * mScaleFactor)) / 2; pivotPointY = (((float) getLayoutParams().height - borderWidth) - (int) (height * mScaleFactor)) / 2; super.setImageDrawable(drawable); } float pivotPointX = 0f; float pivotPointY = 0f; private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { mScaleFactor *= detector.getScaleFactor(); pivotPointX = detector.getFocusX(); pivotPointY = detector.getFocusY(); Log.d(LOG_TAG, "mScaleFactor " + mScaleFactor); Log.d(LOG_TAG, "pivotPointY " + pivotPointY + ", pivotPointX= " + pivotPointX); mScaleFactor = Math.max(0.05f, mScaleFactor); invalidate(); return true; } } </code></pre> <p>And here how I used it within my activity.</p> <pre><code>ImageView imageView = (ImageView) findViewById(R.id.imgView); int hMargin = (int) (displayMetrics.widthPixels * .10); int vMargin = (int) (displayMetrics.heightPixels * .10); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(displayMetrics.widthPixels - (hMargin * 2), (int)(displayMetrics.heightPixels - btnCamera.getHeight()) - (vMargin * 2)); params.leftMargin = hMargin; params.topMargin = vMargin; imageView.setLayoutParams(params); imageView.setImageDrawable(drawable); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload