Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to properly set fixTransX & fixTransY of TouchImageView to implement doubleTap to ZoomOut?
    text
    copied!<p>I am using <code>TouchImageView</code> from <a href="https://github.com/MikeOrtiz/TouchImageView/blob/master/src/com/example/touch/TouchImageView.java" rel="nofollow">here</a>. </p> <p>I am trying to implement <code>ZoomOut</code> for double tap. I have done it partially. But, I am facing some issues when zoomed out. If I zoom the Image &amp; if I give a double tap, then image is not getting rendered properly.</p> <p>Here is my modified version</p> <p>TouchImageView.java</p> <pre><code>package com.bharath.downloadissuedemo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; import android.widget.ImageView; public class TouchImageView extends ImageView { Matrix 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; int viewWidth, viewHeight; static final int CLICK = 3; float saveScale = 1f; protected float origWidth, origHeight; int oldMeasuredWidth, oldMeasuredHeight; GestureDetector gestureDetector; ScaleGestureDetector mScaleDetector; Context context; public TouchImageView(Context context) { super(context); sharedConstructing(context); gestureDetector = new GestureDetector(getContext(), new GestureListener(this)); } public TouchImageView(Context context, AttributeSet attrs) { super(context, attrs); sharedConstructing(context); gestureDetector = new GestureDetector(getContext(), new GestureListener(this)); } private void sharedConstructing(Context context) { super.setClickable(true); this.context = context; mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); matrix = new Matrix(); m = new float[9]; setImageMatrix(matrix); setScaleType(ScaleType.MATRIX); setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { mScaleDetector.onTouchEvent(event); PointF curr = new PointF(event.getX(), event.getY()); switch (event.getAction() &amp; MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: last.set(curr); 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 fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale); float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale); matrix.postTranslate(fixTransX, fixTransY); fixTrans(); 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 &lt; CLICK &amp;&amp; yDiff &lt; CLICK) performClick(); break; case MotionEvent.ACTION_POINTER_UP: mode = NONE; break; } setImageMatrix(matrix); invalidate(); return gestureDetector.onTouchEvent(event); // indicate event was handled } }); } 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 = detector.getScaleFactor(); float origScale = saveScale; System.out.println("Orig Scale = "+origScale); saveScale *= mScaleFactor; System.out.println("Sace Scale = "+saveScale); System.out.println("m Scale Factor = "+mScaleFactor); if (saveScale &gt; maxScale) { saveScale = maxScale; mScaleFactor = maxScale / origScale; } else if (saveScale &lt; minScale) { saveScale = minScale; mScaleFactor = minScale / origScale; } if (origWidth * saveScale &lt;= viewWidth || origHeight * saveScale &lt;= viewHeight) matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2, viewHeight / 2); else matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); fixTrans(); return true; } } void fixTrans() { matrix.getValues(m); float transX = m[Matrix.MTRANS_X]; float transY = m[Matrix.MTRANS_Y]; float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale); float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale); System.out.println("Translation X ="+fixTransX); System.out.println("Translation Y ="+fixTransY); ((ViewPagerInterface)getContext()).enable(); if (fixTransX != 0 || fixTransY != 0) { matrix.postTranslate(fixTransX, fixTransY); } else if (saveScale!=1.0) { ((ViewPagerInterface)getContext()).disable(); } } float getFixTrans(float trans, float viewSize, float contentSize) { float minTrans, maxTrans; if (contentSize &lt;= viewSize) { minTrans = 0; maxTrans = viewSize - contentSize; } else { minTrans = viewSize - contentSize; maxTrans = 0; } if (trans &lt; minTrans) return -trans + minTrans; if (trans &gt; maxTrans) return -trans + maxTrans; return 0; } float getFixDragTrans(float delta, float viewSize, float contentSize) { if (contentSize &lt;= viewSize) { return 0; } return delta; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); viewWidth = MeasureSpec.getSize(widthMeasureSpec); viewHeight = MeasureSpec.getSize(heightMeasureSpec); // // Rescales image on rotation // if (oldMeasuredHeight == viewWidth &amp;&amp; oldMeasuredHeight == viewHeight || viewWidth == 0 || viewHeight == 0) return; oldMeasuredHeight = viewHeight; oldMeasuredWidth = viewWidth; if (saveScale == 1) { //Fit to screen. float scale; Drawable drawable = getDrawable(); if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0) return; int bmWidth = drawable.getIntrinsicWidth(); int bmHeight = drawable.getIntrinsicHeight(); Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight); float scaleX = (float) viewWidth / (float) bmWidth; float scaleY = (float) viewHeight / (float) bmHeight; scale = Math.min(scaleX, scaleY); matrix.setScale(scale, scale); // Center the image float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight); float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth); redundantYSpace /= (float) 2; redundantXSpace /= (float) 2; matrix.postTranslate(redundantXSpace, redundantYSpace); origWidth = viewWidth - 2 * redundantXSpace; origHeight = viewHeight - 2 * redundantYSpace; setImageMatrix(matrix); } fixTrans(); } private class GestureListener extends GestureDetector.SimpleOnGestureListener { public TouchImageView touchImageView=null; public GestureListener(TouchImageView tmv) { touchImageView=tmv; } @Override public boolean onDown(MotionEvent e) { return false; } // event when double tap occurs @Override public boolean onDoubleTap(MotionEvent e) { if (saveScale&gt;1.0f) { Drawable d = getDrawable(); Bitmap bmp = ((BitmapDrawable)d).getBitmap(); System.out.println("bmp Width = "+bmp.getWidth()); System.out.println("bmp Height = "+bmp.getHeight()); System.out.println("Original Width = "+origWidth); System.out.println("Original Height = "+origHeight); System.out.println("View Width "+viewWidth); System.out.println("View height"+viewHeight); float scaleX= viewWidth/(origWidth*saveScale); float scaleY =viewHeight/(origHeight*saveScale); float finalScale = Math.min(scaleX, scaleY); matrix.postScale(finalScale, finalScale, viewWidth / 2, viewHeight / 2); saveScale=1.0f; // // float redundantYSpace = (float) viewHeight - (finalScale * (float) bmp.getHeight()); // float redundantXSpace = (float) viewWidth - (finalScale * (float) bmp); // redundantYSpace /= (float) 2; // redundantXSpace /= (float) 2; // matrix.postTranslate(redundantXSpace, redundantYSpace); matrix.getValues(m); float transX = m[Matrix.MTRANS_X]; float transY = m[Matrix.MTRANS_Y]; float fixTransX = getFixTrans(transX, viewWidth, origWidth * finalScale); float fixTransY = getFixTrans(transY, viewHeight, origHeight * finalScale); // System.out.println("Translation X ="+transX); System.out.println("Translation Y ="+transY); System.out.println("Fix X ="+fixTransX); System.out.println("Fix Y ="+fixTransY); ((ViewPagerInterface)getContext()).enable(); matrix.postTranslate(fixTransX, fixTransY); } // fixTrans(); // System.out.println("Intrinsic Width "+bmp.getWidth()); // System.out.println("Intrinsic Height "+bmp.getHeight()); // RectF drawableRect = new RectF(0, 0,bmp.getWidth(),bmp.getHeight()); // RectF viewRect = new RectF(0, 0,getWidth(), getHeight()); // m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER); // setScale(,); // setScaleX(getWidth()/bmp.getWidth()); // setScaleY( getHeight()/bmp.getHeight()); //setScaleX(scaleX)// saveScale=1.0f; // setImageMatrix(m); // invalidate(); return true; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { // System.out.println("SIngle Tap Occurred"); // touchImageView.saveScale=1.0f; // touchImageView.invalidate(); return super.onSingleTapConfirmed(e); } } } </code></pre> <p>In the above code, please see the method</p> <pre><code> public boolean onDoubleTap(MotionEvent e) </code></pre> <p>What was the mistake I made in the above method?</p>
 

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