主体

public class ZoomImageView extends ImageView implements ScaleGestureDetector.OnScaleGestureListener,        View.OnTouchListener, ViewTreeObserver.OnGlobalLayoutListener {    private static final String TAG = ZoomImageView.class.getSimpleName();    public static final float SCALE_MAX = 4.0f;    private static final float SCALE_MID = 2.0f;    /**     * 初始化时的缩放比例,如果图片宽或高大于屏幕,此值将小于0     */    private float initScale = 1.0f;    private boolean once = true;    /**     * 用于寄存矩阵的9个值     */    private final float[] matrixValues = new float[9];    /**     * 缩放的手势检测     */    private ScaleGestureDetector mScaleGestureDetector = null;    private final Matrix mScaleMatrix = new Matrix();    /**     * 用于双击检测     */    private GestureDetector mGestureDetector;    private OnZoomImageViewSingleClickListener listener;    /**     * @date:2017/11/16/016     * @author:平sir     * @desc: 初始化拦挡单击事件的接口对象     */    public void setListener(OnZoomImageViewSingleClickListener listener) {        this.listener = listener;    }    public OnZoomImageViewSingleClickListener getListener() {        return listener;    }    private boolean isAutoScale;    private int mTouchSlop;    private float mLastX;    private float mLastY;    private boolean isCanDrag;    private int lastPointerCount;    private boolean isCheckTopAndBottom = true;    private boolean isCheckLeftAndRight = true;    public ZoomImageView(Context context) {        this(context, null);    }    public ZoomImageView(Context context, AttributeSet attrs) {        super(context, attrs);        super.setScaleType(ScaleType.MATRIX);        mGestureDetector = new GestureDetector(context,                new GestureDetector.SimpleOnGestureListener() {                    @Override                    public boolean onDoubleTap(MotionEvent e) {                        if (isAutoScale)                            return true;                        float x = e.getX();                        float y = e.getY();                        if (getScale() < SCALE_MID) {                            ZoomImageView.this.postDelayed(                                    new AutoScaleRunnable(SCALE_MID, x, y), 16);                            isAutoScale = true;                        } else if (getScale() >= SCALE_MID                                && getScale() < SCALE_MAX) {                            ZoomImageView.this.postDelayed(                                    new AutoScaleRunnable(SCALE_MAX, x, y), 16);                            isAutoScale = true;                        } else {                            ZoomImageView.this.postDelayed(                                    new AutoScaleRunnable(initScale, x, y), 16);                            isAutoScale = true;                        }                        return true;                    }                });        mScaleGestureDetector = new ScaleGestureDetector(context, this);        this.setOnTouchListener(this);    }    /**     * 主动缩放的工作     *     * @author zhy     */    private class AutoScaleRunnable implements Runnable {        static final float BIGGER = 1.07f;        static final float SMALLER = 0.93f;        private float mTargetScale;        private float tmpScale;        /**         * 缩放的核心         */        private float x;        private float y;        /**         * 传入指标缩放值,依据目标值与以后值,判断应该放大还是放大         *         * @param targetScale         */        public AutoScaleRunnable(float targetScale, float x, float y) {            this.mTargetScale = targetScale;            this.x = x;            this.y = y;            if (getScale() < mTargetScale) {                tmpScale = BIGGER;            } else {                tmpScale = SMALLER;            }        }        @Override        public void run() {            // 进行缩放            mScaleMatrix.postScale(tmpScale, tmpScale, x, y);            checkBorderAndCenterWhenScale();            setImageMatrix(mScaleMatrix);            final float currentScale = getScale();            // 如果值在非法范畴内,持续缩放            if (((tmpScale > 1f) && (currentScale < mTargetScale))                    || ((tmpScale < 1f) && (mTargetScale < currentScale))) {                ZoomImageView.this.postDelayed(this, 16);            } else            // 设置为指标的缩放比例            {                final float deltaScale = mTargetScale / currentScale;                mScaleMatrix.postScale(deltaScale, deltaScale, x, y);                checkBorderAndCenterWhenScale();                setImageMatrix(mScaleMatrix);                isAutoScale = false;            }        }    }    @SuppressLint("NewApi")    @Override    public boolean onScale(ScaleGestureDetector detector) {        float scale = getScale();        float scaleFactor = detector.getScaleFactor();        if (getDrawable() == null)            return true;        /**         * 缩放的范畴管制         */        if ((scale < SCALE_MAX && scaleFactor > 1.0f)                || (scale > initScale && scaleFactor < 1.0f)) {            /**             * 最大值最小值判断             */            if (scaleFactor * scale < initScale) {                scaleFactor = initScale / scale;            }            if (scaleFactor * scale > SCALE_MAX) {                scaleFactor = SCALE_MAX / scale;            }            /**             * 设置缩放比例             */            mScaleMatrix.postScale(scaleFactor, scaleFactor,                    detector.getFocusX(), detector.getFocusY());            checkBorderAndCenterWhenScale();            setImageMatrix(mScaleMatrix);        }        return true;    }    /**     * 在缩放时,进行图片显示范畴的管制     */    private void checkBorderAndCenterWhenScale() {        RectF rect = getMatrixRectF();        float deltaX = 0;        float deltaY = 0;        int width = getWidth();        int height = getHeight();        // 如果宽或高大于屏幕,则管制范畴        if (rect.width() >= width) {            if (rect.left > 0) {                deltaX = -rect.left;            }            if (rect.right < width) {                deltaX = width - rect.right;            }        }        if (rect.height() >= height) {            if (rect.top > 0) {                deltaY = -rect.top;            }            if (rect.bottom < height) {                deltaY = height - rect.bottom;            }        }        // 如果宽或高小于屏幕,则让其居中        if (rect.width() < width) {            deltaX = width * 0.5f - rect.right + 0.5f * rect.width();        }        if (rect.height() < height) {            deltaY = height * 0.5f - rect.bottom + 0.5f * rect.height();        }        mScaleMatrix.postTranslate(deltaX, deltaY);    }    /**     * 依据以后图片的Matrix取得图片的范畴     *     * @return     */    private RectF getMatrixRectF() {        Matrix matrix = mScaleMatrix;        RectF rect = new RectF();        Drawable d = getDrawable();        if (null != d) {            rect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());            matrix.mapRect(rect);        }        return rect;    }    @Override    public boolean onScaleBegin(ScaleGestureDetector detector) {        return true;    }    @Override    public void onScaleEnd(ScaleGestureDetector detector) {    }    @Override    public boolean onTouch(View v, MotionEvent event) {        /**         * 设置拦挡单击事件         */        mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {            @Override            public boolean onSingleTapConfirmed(MotionEvent motionEvent) {                if (listener != null)                    listener.onClick();                return false;            }            @Override            public boolean onDoubleTap(MotionEvent e) {                if (isAutoScale)                    return true;                float x = e.getX();                float y = e.getY();                if (getScale() < SCALE_MID) {                    ZoomImageView.this.postDelayed(                            new AutoScaleRunnable(SCALE_MID, x, y), 16);                    isAutoScale = true;                } else if (getScale() >= SCALE_MID                        && getScale() < SCALE_MAX) {                    ZoomImageView.this.postDelayed(                            new AutoScaleRunnable(SCALE_MAX, x, y), 16);                    isAutoScale = true;                } else {                    ZoomImageView.this.postDelayed(                            new AutoScaleRunnable(initScale, x, y), 16);                    isAutoScale = true;                }                return true;            }            @Override            public boolean onDoubleTapEvent(MotionEvent motionEvent) {                return false;            }        });        if (mGestureDetector.onTouchEvent(event))            return true;        mScaleGestureDetector.onTouchEvent(event);        float x = 0, y = 0;        // 拿到触摸点的个数        final int pointerCount = event.getPointerCount();        // 失去多个触摸点的x与y均值        for (int i = 0; i < pointerCount; i++) {            x += event.getX(i);            y += event.getY(i);        }        x = x / pointerCount;        y = y / pointerCount;        /**         * 每当触摸点发生变化时,重置mLasX , mLastY         */        if (pointerCount != lastPointerCount) {            isCanDrag = false;            mLastX = x;            mLastY = y;        }        lastPointerCount = pointerCount;        RectF rectF = getMatrixRectF();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                if (rectF.width() > getWidth() || rectF.height() > getHeight()) {                    getParent().requestDisallowInterceptTouchEvent(true);                }                break;            case MotionEvent.ACTION_MOVE:                if (rectF.width() > getWidth() || rectF.height() > getHeight()) {                    getParent().requestDisallowInterceptTouchEvent(true);                }                float dx = x - mLastX;                float dy = y - mLastY;                if (!isCanDrag) {                    isCanDrag = isCanDrag(dx, dy);                }                if (isCanDrag) {                    if (getDrawable() != null) {                        // if (getMatrixRectF().left == 0 && dx > 0)                        // {                        // getParent().requestDisallowInterceptTouchEvent(false);                        // }                        //                        // if (getMatrixRectF().right == getWidth() && dx < 0)                        // {                        // getParent().requestDisallowInterceptTouchEvent(false);                        // }                        isCheckLeftAndRight = isCheckTopAndBottom = true;                        // 如果宽度小于屏幕宽度,则禁止左右挪动                        if (rectF.width() < getWidth()) {                            dx = 0;                            isCheckLeftAndRight = false;                        }                        // 如果高度小雨屏幕高度,则禁止高低挪动                        if (rectF.height() < getHeight()) {                            dy = 0;                            isCheckTopAndBottom = false;                        }                        mScaleMatrix.postTranslate(dx, dy);                        checkMatrixBounds();                        setImageMatrix(mScaleMatrix);                    }                }                mLastX = x;                mLastY = y;                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                lastPointerCount = 0;                break;        }        return true;    }    /**     * @date:2017/11/16/016     * @author:平sir     * @desc: 定义接口,用于拦挡单击事件     */    public interface OnZoomImageViewSingleClickListener {        void onClick();    }    /**     * 取得以后的缩放比例     *     * @return     */    public final float getScale() {        mScaleMatrix.getValues(matrixValues);        return matrixValues[Matrix.MSCALE_X];    }    @Override    protected void onAttachedToWindow() {        super.onAttachedToWindow();        getViewTreeObserver().addOnGlobalLayoutListener(this);    }    @SuppressWarnings("deprecation")    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        getViewTreeObserver().removeGlobalOnLayoutListener(this);    }    @Override    public void onGlobalLayout() {        if (once) {            Drawable d = getDrawable();            if (d == null)                return;            int width = getWidth();            int height = getHeight();            // 拿到图片的宽和高            int dw = d.getIntrinsicWidth();            int dh = d.getIntrinsicHeight();            float scale = 1.0f;            // 如果图片的宽或者高大于屏幕,则缩放至屏幕的宽或者高            if (dw > width && dh <= height) {                scale = width * 1.0f / dw;            }            if (dh > height && dw <= width) {                scale = height * 1.0f / dh;            }            // 如果宽和高都大于屏幕,则让其按按比例适应屏幕大小            if (dw > width && dh > height) {                scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);            }            initScale = scale;            mScaleMatrix.postTranslate((float) (width - dw) / 2, (float) (height - dh) / 2);            mScaleMatrix.postScale(scale, scale, (float) getWidth() / 2,                    (float) getHeight() / 2);            // 图片挪动至屏幕核心            setImageMatrix(mScaleMatrix);            once = false;        }    }    /**     * 挪动时,进行边界判断,次要判断宽或高大于屏幕的     */    private void checkMatrixBounds() {        RectF rect = getMatrixRectF();        float deltaX = 0, deltaY = 0;        final float viewWidth = getWidth();        final float viewHeight = getHeight();        // 判断挪动或缩放后,图片显示是否超出屏幕边界        if (rect.top > 0 && isCheckTopAndBottom) {            deltaY = -rect.top;        }        if (rect.bottom < viewHeight && isCheckTopAndBottom) {            deltaY = viewHeight - rect.bottom;        }        if (rect.left > 0 && isCheckLeftAndRight) {            deltaX = -rect.left;        }        if (rect.right < viewWidth && isCheckLeftAndRight) {            deltaX = viewWidth - rect.right;        }        mScaleMatrix.postTranslate(deltaX, deltaY);    }    /**     * 是否是推动行为     *     * @param dx     * @param dy     * @return     */    private boolean isCanDrag(float dx, float dy) {        return Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;    }}

应用

  <ZoomImageView        android:id="@+id/iv_image"        android:layout_width="match_parent"        android:layout_height="match_parent"    />

可应用Glide

 Glide.with(this).load(getResources().getDrawable(R.mipmap.ic_warm)).into(imageView);