如何将缩放后的图像重置为原始图像

2024-01-15

我正在使用TouchImageView课程可在https://github.com/MikeOrtiz/TouchImageView https://github.com/MikeOrtiz/TouchImageView.

当我从缩放图像移动到下一个图像并返回到上一个图像时,它仍然可以缩放。

我想在滑动到上一张图像时将缩放图像重置为正常位置

并通过参考这个问题得到答案如何将图像重置到原始位置 https://stackoverflow.com/questions/17022637/how-to-reset-an-image-to-the-original-position但我不知道这个方法到底应该放在这个库的哪里,所以你能帮我指导一下吗?

提前致谢。

public class TouchImageView extends ImageView {

private static final String DEBUG = "DEBUG";

//
// SuperMin and SuperMax multipliers. Determine how much the image can be
// zoomed below or above the zoom boundaries, before animating back to the
// min/max zoom boundary.
//
private static final float SUPER_MIN_MULTIPLIER = .75f;
private static final float SUPER_MAX_MULTIPLIER = 1.25f;

//
// Scale of image ranges from minScale to maxScale, where minScale == 1
// when the image is stretched to fit view.
//
private float normalizedScale;

//
// Matrix applied to image. MSCALE_X and MSCALE_Y should always be equal.
// MTRANS_X and MTRANS_Y are the other values used. prevMatrix is the matrix
// saved prior to the screen rotating.
//
private Matrix matrix, prevMatrix;

private boolean onTouch = false;

private static enum State { NONE, DRAG, ZOOM, FLING, ANIMATE_ZOOM };
private State state;

private float minScale;
private float maxScale;
private float superMinScale;
private float superMaxScale;
private float[] m;

private Context context;
private Fling fling;

private ScaleType mScaleType;

private boolean onDrawReady;
private ZoomVariables delayedZoomVariables;

//
// Size of view and previous view size (ie before rotation)
//
private int viewWidth, viewHeight, prevViewWidth, prevViewHeight;

//
// Size of image when it is stretched to fit view. Before and After rotation.
//
private float matchViewWidth, matchViewHeight, prevMatchViewWidth, prevMatchViewHeight;

private ScaleGestureDetector mScaleDetector;
private GestureDetector mGestureDetector;

public TouchImageView(Context context) {
    super(context);
    sharedConstructing(context);
}

public TouchImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    sharedConstructing(context);
}

public TouchImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    sharedConstructing(context);
}

OnScaleChangeListener _scaleChangeListener;             // Coded by siva // interface object for detecting the single and double tap on imageview 


public interface OnScaleChangeListener {
    public void onSingleTabfromTouchImage(boolean isSingleTabClick);
    public void onDoubleTapfromTouchImage(boolean isDoubleTapClick);
}

public synchronized void setOnScaleChangeListener(OnScaleChangeListener listener){
    _scaleChangeListener = listener;
}

private void sharedConstructing(Context context) {
    super.setClickable(true);
    this.context = context;
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    mGestureDetector = new GestureDetector(context, new GestureListener());
    matrix = new Matrix();
    prevMatrix = new Matrix();
    m = new float[9];
    normalizedScale = 1;
    if (mScaleType == null) {
        mScaleType = ScaleType.FIT_CENTER;
    }
    minScale = 1;
    maxScale = 3;
    superMinScale = SUPER_MIN_MULTIPLIER * minScale;
    superMaxScale = SUPER_MAX_MULTIPLIER * maxScale;
    setImageMatrix(matrix);
    setScaleType(ScaleType.MATRIX);
    setState(State.NONE);
    setOnTouchListener(new TouchImageViewListener());
    onDrawReady = false;
}

@Override
public void setImageResource(int resId) {
    super.setImageResource(resId);
    savePreviousImageValues();
    fitImageToView();
}

@Override
public void setImageBitmap(Bitmap bm) {
    super.setImageBitmap(bm);
    savePreviousImageValues();
    fitImageToView();
}

@Override
public void setImageDrawable(Drawable drawable) {
    super.setImageDrawable(drawable);
    savePreviousImageValues();
    fitImageToView();
}

@Override
public void setImageURI(Uri uri) {
    super.setImageURI(uri);
    savePreviousImageValues();
    fitImageToView();
}

@Override
public void setScaleType(ScaleType type) {
    if (type == ScaleType.FIT_START || type == ScaleType.FIT_END) {
        throw new UnsupportedOperationException("TouchImageView does not support FIT_START or FIT_END");
    }
    if (type == ScaleType.MATRIX) {
        super.setScaleType(ScaleType.MATRIX);

    } else {
        mScaleType = type;
    }
}

@Override
public ScaleType getScaleType() {
    return mScaleType;
}

/**
 * Returns false if image is in initial, unzoomed state. False, otherwise.
 * @return true if image is zoomed
 */
public boolean isZoomed() {

    if(normalizedScale > 1)
        return true;
    else
        return false;
    //return normalizedScale != 1;
}

/**
 * Return a bitmap of the zoomed image as it appears within the view. This essentially
 * acts as a "screenshot" of the view and the size of the final bitmap is limited to the
 * resolution of the view itself.
 * @return bitmap of zoomed image
 */
public Bitmap getZoomedImage() {
    Bitmap bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);                
    Canvas canvas = new Canvas(bitmap);
    layout(0, 0, viewWidth, viewHeight);
    draw(canvas);
    return bitmap;
}

/**
 * Return a bitmap of the zoomed image. This method is different from getZoomedImage() because
 * it cuts the image directly from the drawable source, and thus, is not limited by the resolution
 * of the view. Not supported with FIT_XY.
 * @return bitmap of zoomed image
 */
public Bitmap getZoomedImageFromSource() {
    if (mScaleType == ScaleType.FIT_XY) {
        throw new UnsupportedOperationException("getZoomedImageFromSource() not supported with FIT_XY");
    }
    Bitmap bitmap = ((BitmapDrawable) getDrawable()).getBitmap();
    Rect r = getZoomedRect();
    if (r.width() <= 0 || r.height() <= 0) {
        return null;
    }
    return Bitmap.createBitmap(bitmap, r.left, r.top, r.width(), r.height());
}

/**
 * Return a Rect representing the zoomed image in the coordinate system of the drawable source.
 * @return rect representing zoomed image
 */
public Rect getZoomedRect() {
    if (mScaleType == ScaleType.FIT_XY) {
        throw new UnsupportedOperationException("getZoomedRect() not supported with FIT_XY");
    }
    PointF topLeft = getDrawablePointFromTouchPoint(0,0);
    PointF bottomRight = getDrawablePointFromTouchPoint(viewWidth, viewHeight);
    return new Rect((int) topLeft.x, (int) topLeft.y,(int) bottomRight.x, (int) bottomRight.y);
}

/**
 * Save the current matrix and view dimensions
 * in the prevMatrix and prevView variables.
 */
private void savePreviousImageValues() {
    if (matrix != null) {
        matrix.getValues(m);
        prevMatrix.setValues(m);
        prevMatchViewHeight = matchViewHeight;
        prevMatchViewWidth = matchViewWidth;
        prevViewHeight = viewHeight;
        prevViewWidth = viewWidth;
    }
}

@Override
public Parcelable onSaveInstanceState() {
    Bundle bundle = new Bundle();
    bundle.putParcelable("instanceState", super.onSaveInstanceState());
    bundle.putFloat("saveScale", normalizedScale);
    bundle.putFloat("matchViewHeight", matchViewHeight);
    bundle.putFloat("matchViewWidth", matchViewWidth);
    bundle.putInt("viewWidth", viewWidth);
    bundle.putInt("viewHeight", viewHeight);
    matrix.getValues(m);
    bundle.putFloatArray("matrix", m);
    return bundle;
}

@Override
public void onRestoreInstanceState(Parcelable state) {
    if (state instanceof Bundle) {
        Bundle bundle = (Bundle) state;
        normalizedScale = bundle.getFloat("saveScale");
        m = bundle.getFloatArray("matrix");
        prevMatrix.setValues(m);
        prevMatchViewHeight = bundle.getFloat("matchViewHeight");
        prevMatchViewWidth = bundle.getFloat("matchViewWidth");
        prevViewHeight = bundle.getInt("viewHeight");
        prevViewWidth = bundle.getInt("viewWidth");
        super.onRestoreInstanceState(bundle.getParcelable("instanceState"));
        return;
    }

    super.onRestoreInstanceState(state);
}

@Override
protected void onDraw(Canvas canvas) {
    onDrawReady = true;
    if (delayedZoomVariables != null) {
        setZoom(delayedZoomVariables.scale, delayedZoomVariables.focusX, delayedZoomVariables.focusY, delayedZoomVariables.scaleType);
        delayedZoomVariables = null;
    }
    super.onDraw(canvas);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //savePreviousImageValues();
    resetZoom();
}

/**
 * Get the max zoom multiplier.
 * @return max zoom multiplier.
 */
public float getMaxZoom() {
    return maxScale;
}

/**
 * Set the max zoom multiplier. Default value: 3.
 * @param max max zoom multiplier.
 */
public void setMaxZoom(float max) {
    maxScale = max;
    superMaxScale = SUPER_MAX_MULTIPLIER * maxScale;
}

/**
 * Get the min zoom multiplier.
 * @return min zoom multiplier.
 */
public float getMinZoom() {
    return minScale;
}

/**
 * Get the current zoom. This is the zoom relative to the initial
 * scale, not the original resource.
 * @return current zoom multiplier.
 */
public float getCurrentZoom() {
    return normalizedScale;
}

/**
 * Set the min zoom multiplier. Default value: 1.
 * @param min min zoom multiplier.
 */
public void setMinZoom(float min) {
    minScale = min;
    superMinScale = SUPER_MIN_MULTIPLIER * minScale;
}

/**
 * Reset zoom and translation to initial state.
 */
public void resetZoom() {
    normalizedScale = 1;
    fitImageToView();
}

/**
 * Set zoom to the specified scale. Image will be centered by default.
 * @param scale
 */
public void setZoom(float scale) {
    setZoom(scale, 0.5f, 0.5f);
}

/**
 * Set zoom to the specified scale. Image will be centered around the point
 * (focusX, focusY). These floats range from 0 to 1 and denote the focus point
 * as a fraction from the left and top of the view. For example, the top left 
 * corner of the image would be (0, 0). And the bottom right corner would be (1, 1).
 * @param scale
 * @param focusX
 * @param focusY
 */
public void setZoom(float scale, float focusX, float focusY) {
    setZoom(scale, focusX, focusY, mScaleType);
}

/**
 * Set zoom to the specified scale. Image will be centered around the point
 * (focusX, focusY). These floats range from 0 to 1 and denote the focus point
 * as a fraction from the left and top of the view. For example, the top left 
 * corner of the image would be (0, 0). And the bottom right corner would be (1, 1).
 * @param scale
 * @param focusX
 * @param focusY
 * @param scaleType
 */
public void setZoom(float scale, float focusX, float focusY, ScaleType scaleType) {
    //
    // setZoom can be called before the image is on the screen, but at this point, 
    // image and view sizes have not yet been calculated in onMeasure. Thus, we should
    // delay calling setZoom until the view has been measured.
    //
    if (!onDrawReady) {
        delayedZoomVariables = new ZoomVariables(scale, focusX, focusY, scaleType);
        return;
    }

    setScaleType(scaleType);
    resetZoom();
    scaleImage(scale, viewWidth / 2, viewHeight / 2, false);
    matrix.getValues(m);
    m[Matrix.MTRANS_X] = -((focusX * getImageWidth()) - (viewWidth * 0.5f));
    m[Matrix.MTRANS_Y] = -((focusY * getImageHeight()) - (viewHeight * 0.5f));
    matrix.setValues(m);
    fixTrans();
    setImageMatrix(matrix);
}

/**
 * Set zoom parameters equal to another TouchImageView. Including scale, position,
 * and ScaleType.
 * @param TouchImageView
 */
public void setZoom(TouchImageView img) {
    PointF center = img.getCenterOfZoomedImage();
    setZoom(img.getCurrentZoom(), center.x, center.y, img.getScaleType());
}

/**
 * For a given point on the view (ie, a touch event), returns the
 * point relative to the original drawable's coordinate system.
 * @param x
 * @param y
 * @return PointF relative to original drawable's coordinate system.
 */
public PointF getDrawablePointFromTouchPoint(float x, float y) {
    return transformCoordTouchToBitmap(x, y, true);
}

/**
 * For a given point on the view (ie, a touch event), returns the
 * point relative to the original drawable's coordinate system.
 * @param p
 * @return PointF relative to original drawable's coordinate system.
 */
public PointF getDrawablePointFromTouchPoint(PointF p) {
    return transformCoordTouchToBitmap(p.x, p.y, true);
}

/**
 * Return the point at the center of the zoomed image. The PointF coordinates range
 * in value between 0 and 1 and the focus point is denoted as a fraction from the left 
 * and top of the view. For example, the top left corner of the image would be (0, 0). 
 * And the bottom right corner would be (1, 1).
 * @return PointF representing center of zoomed image
 */
public PointF getCenterOfZoomedImage() {
    Drawable drawable = getDrawable();
    if (drawable == null) {
        return null;
    }
    int drawableWidth = drawable.getIntrinsicWidth();
    int drawableHeight = drawable.getIntrinsicHeight();

    PointF point = getDrawablePointFromTouchPoint(viewWidth / 2, viewHeight / 2);
    point.x /= drawableWidth;
    point.y /= drawableHeight;
    return point;
}

/**
 * Performs boundary checking and fixes the image matrix if it 
 * is out of bounds.
 */
private void fixTrans() {
    matrix.getValues(m);
    float transX = m[Matrix.MTRANS_X];
    float transY = m[Matrix.MTRANS_Y];

    float fixTransX = getFixTrans(transX, viewWidth, getImageWidth());
    float fixTransY = getFixTrans(transY, viewHeight, getImageHeight());

    if (fixTransX != 0 || fixTransY != 0) {
        matrix.postTranslate(fixTransX, fixTransY);
    }
}

/**
 * When transitioning from zooming from focus to zoom from center (or vice versa)
 * the image can become unaligned within the view. This is apparent when zooming
 * quickly. When the content size is less than the view size, the content will often
 * be centered incorrectly within the view. fixScaleTrans first calls fixTrans() and 
 * then makes sure the image is centered correctly within the view.
 */
private void fixScaleTrans() {
    fixTrans();
    matrix.getValues(m);
    if (getImageWidth() < viewWidth) {
        m[Matrix.MTRANS_X] = (viewWidth - getImageWidth()) / 2;
    }

    if (getImageHeight() < viewHeight) {
        m[Matrix.MTRANS_Y] = (viewHeight - getImageHeight()) / 2;
    }
    matrix.setValues(m);
}

private float getFixTrans(float trans, float viewSize, float contentSize) {
    float minTrans, maxTrans;

    if (contentSize <= viewSize) {
        minTrans = 0;
        maxTrans = viewSize - contentSize;

    } else {
        minTrans = viewSize - contentSize;
        maxTrans = 0;
    }

    if (trans < minTrans)
        return -trans + minTrans;
    if (trans > maxTrans)
        return -trans + maxTrans;
    return 0;
}

private float getFixDragTrans(float delta, float viewSize, float contentSize) {
    if (contentSize <= viewSize) {
        return 0;
    }
    return delta;
}

private float getImageWidth() {
    return matchViewWidth * normalizedScale;
}

private float getImageHeight() {
    return matchViewHeight * normalizedScale;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Drawable drawable = getDrawable();
    if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0) {
        setMeasuredDimension(0, 0);
        return;
    }

  /*  if(onTouch){
        //resetZoom();
        onTouch  = false;
    }
    else
        resetZoom();*/

    int drawableWidth = drawable.getIntrinsicWidth();
    int drawableHeight = drawable.getIntrinsicHeight();
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    viewWidth = setViewSize(widthMode, widthSize, drawableWidth);
    viewHeight = setViewSize(heightMode, heightSize, drawableHeight);

    //
    // Set view dimensions
    //
    setMeasuredDimension(viewWidth, viewHeight);

    //
    // Fit content within view
    //
    fitImageToView();
}

/**
 * If the normalizedScale is equal to 1, then the image is made to fit the screen. Otherwise,
 * it is made to fit the screen according to the dimensions of the previous image matrix. This
 * allows the image to maintain its zoom after rotation.
 */
private void fitImageToView() {
    Drawable drawable = getDrawable();
    if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0) {
        return;
    }
    if (matrix == null || prevMatrix == null) {
        return;
    }

    int drawableWidth = drawable.getIntrinsicWidth();
    int drawableHeight = drawable.getIntrinsicHeight();

    //
    // Scale image for view
    //
    float scaleX = (float) viewWidth / drawableWidth;
    float scaleY = (float) viewHeight / drawableHeight;

    switch (mScaleType) {
    case CENTER:
        scaleX = scaleY = 1;
        break;

    case CENTER_CROP:
        scaleX = scaleY = Math.max(scaleX, scaleY);
        break;

    case CENTER_INSIDE:
        scaleX = scaleY = Math.min(1, Math.min(scaleX, scaleY));

    case FIT_CENTER:
        scaleX = scaleY = Math.min(scaleX, scaleY);
        break;

    case FIT_XY:
        break;

    default:
        //
        // FIT_START and FIT_END not supported
        //
        throw new UnsupportedOperationException("TouchImageView does not support FIT_START or FIT_END");

    }

    //
    // Center the image
    //
    float redundantXSpace = viewWidth - (scaleX * drawableWidth);
    float redundantYSpace = viewHeight - (scaleY * drawableHeight);
    matchViewWidth = viewWidth - redundantXSpace;
    matchViewHeight = viewHeight - redundantYSpace;
    if (!isZoomed()) {
        //
        // Stretch and center image to fit view
        //
        matrix.setScale(scaleX, scaleY);
        matrix.postTranslate(redundantXSpace / 2, redundantYSpace / 2);
        normalizedScale = 1;

    } else {
        //
        // These values should never be 0 or we will set viewWidth and viewHeight
        // to NaN in translateMatrixAfterRotate. To avoid this, call savePreviousImageValues
        // to set them equal to the current values.
        //

        if(onTouch){
            if(matchViewWidth > drawableWidth){
                prevMatchViewHeight = 0;
                prevMatchViewWidth = 0;
                savePreviousImageValues();
            }
            onTouch = false;
        }
        if (prevMatchViewWidth == 0 || prevMatchViewHeight == 0) {
            //savePreviousImageValues();
            normalizedScale = 1;
        }

        prevMatrix.getValues(m);

        //
        // Rescale Matrix after rotation
        //
        m[Matrix.MSCALE_X] = matchViewWidth / drawableWidth * normalizedScale;
        m[Matrix.MSCALE_Y] = matchViewHeight / drawableHeight * normalizedScale;

        //
        // TransX and TransY from previous matrix
        //
        float transX = m[Matrix.MTRANS_X];
        float transY = m[Matrix.MTRANS_Y];

        //
        // Width
        //
        float prevActualWidth = prevMatchViewWidth * normalizedScale;
        float actualWidth = getImageWidth();
        translateMatrixAfterRotate(Matrix.MTRANS_X, transX, prevActualWidth, actualWidth, prevViewWidth, viewWidth, drawableWidth);

        //
        // Height
        //
        float prevActualHeight = prevMatchViewHeight * normalizedScale;
        float actualHeight = getImageHeight();
        translateMatrixAfterRotate(Matrix.MTRANS_Y, transY, prevActualHeight, actualHeight, prevViewHeight, viewHeight, drawableHeight);

        //
        // Set the matrix to the adjusted scale and translate values.
        //
        matrix.setValues(m);
    }
    fixTrans();
    setImageMatrix(matrix);
}

/**
 * Set view dimensions based on layout params
 * 
 * @param mode 
 * @param size
 * @param drawableWidth
 * @return
 */
private int setViewSize(int mode, int size, int drawableWidth) {
    int viewSize;
    switch (mode) {
    case MeasureSpec.EXACTLY:
        viewSize = size;
        break;

    case MeasureSpec.AT_MOST:
        viewSize = Math.min(drawableWidth, size);
        break;

    case MeasureSpec.UNSPECIFIED:
        viewSize = drawableWidth;
        break;

    default:
        viewSize = size;
        break;
    }
    return viewSize;
}

/**
 * Gesture Listener detects a single click or long click and passes that on
 * to the view's listener.
 * @author Ortiz
 *
 */
private class GestureListener extends GestureDetector.SimpleOnGestureListener {

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e)
    {
        onTouch = true;
        _scaleChangeListener.onSingleTabfromTouchImage(true);            // set the boolean for single tap //  Coded by siva.
        savePreviousImageValues();
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e)
    {
        performLongClick();
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
    {
        if (fling != null) {
            //
            // If a previous fling is still active, it should be cancelled so that two flings
            // are not run simultaenously.
            //
            fling.cancelFling();
        }
        fling = new Fling((int) velocityX, (int) velocityY);
        compatPostOnAnimation(fling);
        return super.onFling(e1, e2, velocityX, velocityY);
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        boolean consumed = false;



        if (state == State.NONE) {
            float targetZoom = (normalizedScale == minScale) ? maxScale : minScale;
            DoubleTapZoom doubleTap = new DoubleTapZoom(targetZoom, e.getX(), e.getY(), false);
            compatPostOnAnimation(doubleTap);
            consumed = true;
        }
        return consumed;
    }
}

/**
 * Responsible for all touch events. Handles the heavy lifting of drag and also sends
 * touch events to Scale Detector and Gesture Detector.
 * @author Ortiz
 *
 */
private class TouchImageViewListener implements OnTouchListener {

    //
    // Remember last point position for dragging
    //
    private PointF last = new PointF();

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        mScaleDetector.onTouchEvent(event);
        mGestureDetector.onTouchEvent(event);
        PointF curr = new PointF(event.getX(), event.getY());

        if (state == State.NONE || state == State.DRAG || state == State.FLING) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    last.set(curr);
                    if (fling != null)
                        fling.cancelFling();
                    setState(State.DRAG);
                    break;

                case MotionEvent.ACTION_MOVE:
                    if (state == State.DRAG) {
                        float deltaX = curr.x - last.x;
                        float deltaY = curr.y - last.y;
                        float fixTransX = getFixDragTrans(deltaX, viewWidth, getImageWidth());
                        float fixTransY = getFixDragTrans(deltaY, viewHeight, getImageHeight());
                        matrix.postTranslate(fixTransX, fixTransY);
                        fixTrans();
                        last.set(curr.x, curr.y);
                    }
                    break;

                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_POINTER_UP:
                    setState(State.NONE);
                    break;
            }
        }

        setImageMatrix(matrix);
        //
        // indicate event was handled
        //
        return true;
    }
}

/**
 * ScaleListener detects user two finger scaling and scales image.
 * @author Ortiz
 *
 */
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        setState(State.ZOOM);
        return true;
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        scaleImage(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY(), true);
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        super.onScaleEnd(detector);
        setState(State.NONE);
        boolean animateToZoomBoundary = false;
        float targetZoom = normalizedScale;
        if (normalizedScale > maxScale) {
            targetZoom = maxScale;
            animateToZoomBoundary = true;

        } else if (normalizedScale < minScale) {
            targetZoom = minScale;
            animateToZoomBoundary = true;
        }

        if (animateToZoomBoundary) {
            DoubleTapZoom doubleTap = new DoubleTapZoom(targetZoom, viewWidth / 2, viewHeight / 2, true);
            compatPostOnAnimation(doubleTap);
        }
    }
}

private void scaleImage(float deltaScale, float focusX, float focusY, boolean stretchImageToSuper) {

    float lowerScale, upperScale;
    if (stretchImageToSuper) {
        lowerScale = superMinScale;
        upperScale = superMaxScale;

    } else {
        lowerScale = minScale;
        upperScale = maxScale;
    }

    float origScale = normalizedScale;
    normalizedScale *= deltaScale;
    if (normalizedScale > upperScale) {
        normalizedScale = upperScale;
        deltaScale = upperScale / origScale;
    } else if (normalizedScale < lowerScale) {
        normalizedScale = lowerScale;
        deltaScale = lowerScale / origScale;
    }

    matrix.postScale(deltaScale, deltaScale, focusX, focusY);
    fixScaleTrans();
}

所以你的问题的解决方案是,在你的开关盒中触摸图像视图 class

switch (event.getAction()) { }

我们需要再添加一个条件

case MotionEvent.ACTION_CANCEL:
     resetZoom();
     break;

这对我有用,我相信这对你也有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将缩放后的图像重置为原始图像 的相关文章

  • java.lang.IllegalArgumentException:此组件要求您指定有效的 android:textAppearance 属性

    我的布局文件之一中有一个 com google android material button MaterialButton 组件 当我使用最新版本的 Material Components 库 com google android mat
  • 检查 WebView 元素时的 UiAutomator 错误

    I have recently started automation testing in android and was using UiAutomator tool for inspecting UI elements Surprisi
  • Android短音的正确播放方法?

    我正在创建一个应用程序 屏幕上将有多个图像 这些图像将是按钮 点击时会播放短促的声音 我对此进行了研究 只能找到我当前用来播放声音的方法 这似乎根本没有响应 我希望声音能够快速播放并且能够响应多次快速点击 我不确定这在 Android 中是
  • 从响应中获取标头(Retrofit / OkHttp 客户端)

    我正在使用 Retrofit 与 OkHttp 客户端和 Jackson 进行 Json 序列化 并希望获取响应的标头 我知道我可以扩展 OkClient 并拦截它 但这发生在反序列化过程开始之前 我基本上需要的是获取标头以及反序列化的 J
  • 通过 WhatsApp 发送消息

    由于我发现了一些较旧的帖子 表明 Whatsapp 不支持此功能 我想知道是否发生了变化 以及是否有办法打开与我通过意图发送的号码进行 Whatsapp 聊天 UPDATE请参阅https faq whatsapp com en andro
  • 如何在我现有的 Android 应用程序中使用 Telegram API(包括聊天应用程序)?

    我想使用 telegram API 在我现有的 Android 应用程序中开发聊天功能 我不知道如何实施 我认为 看看Telegram 数据库库 测试版 从这里TDLib https core telegram org tdlib 俄语 但
  • Dialog.setTitle 不显示标题

    我正在尝试向我的对话框添加自定义标题 但是每当我运行我的应用程序时 它都不会显示标题 我创建对话框的代码是 final Dialog passwordDialog new Dialog this passwordDialog setCont
  • 以编程方式将文本颜色设置为主要 Android 文本视图

    如何设置我的文本颜色TextView to android textColorPrimary以编程方式 我已经尝试了下面的代码 但它将 textColorPrimary 和 textColorPrimary Inverse 的文本颜色始终设
  • 在 android 中建立与 MySQL 的池连接

    我需要从我的 Android 应用程序访问 MySQL 数据库 现在所有的工作都通过 DriverManager getConnection url 等等 但我必须从多个线程访问数据库 所以我必须使用连接池 问题1 是 com mysql
  • Android Eclipse 上的 Web 服务

    我是 android eclipse java 的新手 事实上这个论坛也是如此 有人遇到过这种情况吗 从用户那里获取输入并通过使用 android eclipse 中的 Web 服务来显示适当的结果 有可用的示例吗 非常感谢 我正在发布教程
  • Android Studio 与本地网络共享上的项目文件

    这是我的设置 Android Studio 项目文件位于 Ubuntu 14 10 盒子上的共享文件夹中 尝试在 Windows 8 机器上运行 Android Studio 1 0 2 并将 U 驱动器映射到包含项目文件的 Ubuntu
  • 使用片段时应用程序崩溃

    我正在处理碎片和 我的代码中有一个我找不到的问题 logcat 指向我的一个片段中的这段代码 Override public View onCreateView LayoutInflater inflater ViewGroup conta
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • Android 中如何通过彩信发送图片?

    我正在开发多媒体应用程序 我正在通过相机捕获一张图像 并希望将该图像和文本发送到其他号码 但我不知道如何通过彩信发送图像 MMS 只是一个 http post 请求 您应该使用执行请求额外的网络功能 final ConnectivityMa
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • 上网本上可以进行Android开发吗? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想使用我的上网本进行 Android 开发 但是当我尝试使用 Eclipse 运行 SDK 时 没有加载任何内容 上网本对于 Android 开发来
  • 问题:为什么React Native Video不能全屏播放视频?

    我正在react native 0 57 7 中为android和ios创建一个应用程序并使用反应本机视频 https github com react native community react native video播放上传到的视频
  • Dagger 2 中“HasFragmentInjector”的实际用法是什么

    我之前已经实现了 dagger2 v2 2 但现在他们也添加了 dagger android 部分 所以我正在用它创建示例项目 我知道旧的方法论 Provide and Modules and 成分等注释 但从 Dagger 2 8 开始
  • Android 后台倒计时器

    我有一个 Android 应用程序 它管理一个倒计时器 类 CountDownTimer 它显示在应用程序屏幕中 以显示到达 00 00 还剩多少时间 我现在的问题是 当我按主页按钮或启动另一个应用程序时 应用程序 计时器不会在后台运行 所
  • Android 屏幕方向错误

    我使用的是 Android HTC HERO 2 1 版本 我写的活动

随机推荐