放大可以移动的ImageView

来源:互联网 发布:mac同时安装两个xcode 编辑:程序博客网 时间:2024/04/28 14:37

转载:http://blog.csdn.net/lmj623565791/article/details/39480503

public class zoomImageView extends ImageView implements ScaleGestureDetector.OnScaleGestureListener,        View.OnTouchListener,ViewTreeObserver.OnGlobalLayoutListener{    private static final  float SCALE_MAX = 4.0f;    //初始化时的缩放比例,如果图片宽或高大于屏幕,此值将小于0;    private float initScale = 1.0f;    //用于存放矩阵的9个值    private final float[] matrixValues = new float[9];    private boolean once = true;    //缩放的手势检测    private ScaleGestureDetector mScaleGestureDetector = null;    private final Matrix mScaleMatrix = new Matrix();    private float scale;    private RectF matrixRectF;    public zoomImageView(Context context) {        this(context,null);    }    public zoomImageView(Context context, AttributeSet attrs) {        super(context, attrs);        super.setScaleType(ScaleType.MATRIX);        mScaleGestureDetector = new ScaleGestureDetector(context, this);        this.setOnTouchListener(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(dw * 1.0f / width, dh * 1.0f / height);            }            initScale = scale;            //图片移到屏幕中心            mScaleMatrix.postTranslate((width - dw)/2,(height - dh)/2);            mScaleMatrix.postScale(scale, scale, getWidth() / 2, getHeight() / 2);            setImageMatrix(mScaleMatrix);            once = false;        }    }    @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, getWidth() / 2, getHeight() / 2);            mScaleMatrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(),detector.getFocusY());            checkBorderAndCenterWhenScale();            setImageMatrix(mScaleMatrix);        }        return true;    }    /**     * 在缩放时,进行图片显示范围的控制     */    private void checkBorderAndCenterWhenScale() {        RectF rectF = getMatrixRectF();        float deltaX= 0,deltaY = 0;        int width = getWidth();        int height = getHeight();        //如果宽或高大于屏幕,则控制范围        if(rectF.width() >= width){            if(rectF.left>0){                deltaX = -rectF.left;            }            if (rectF.right<width){                deltaX  =width - rectF.right;            }        }        if(rectF.height()>=height){            if (rectF.top >0){                deltaY = -rectF.top;            }            if(rectF.bottom < height){                deltaY = height - rectF.bottom;            }        }        //如果宽度或高度小于屏幕,则居中、        if (rectF.width()<width){            deltaX = width*0.5f  - rectF.right + 0.5f*rectF.width();        }        if(rectF.height()<height){            deltaY = height*0.5f - rectF.bottom + 0.5f*rectF.height();        }        mScaleMatrix.postTranslate(deltaX, deltaY);    }    @Override    public boolean onScaleBegin(ScaleGestureDetector detector) {        return true;    }    @Override    public void onScaleEnd(ScaleGestureDetector detector) {    }//用于双击检测    int lastPointerCount,mTouchSlop;    boolean isCanDrag,isAutoScale,isCheckTopAndBottom = true,isChekLeftAndRight = true;    float mLastX,mLastY;    @Override    public boolean onTouch(View v, MotionEvent event) {        mScaleGestureDetector.onTouchEvent(event);        float x = 0,y = 0;        //拿到触摸点的个数        final int pointerCounter = event.getPointerCount();        //得到多个触摸点的x与y均值        for (int i = 0; i < pointerCounter; i++) {            x+=event.getX(i);            y+=event.getY(i);        }        x= x/pointerCounter;        y = y/pointerCounter;        //每当触摸点发生变化时,重置mLasX,mLastY        if(pointerCounter!= lastPointerCount){              isCanDrag = false;             mLastX = x;            mLastY  =y;        }        lastPointerCount = pointerCounter;        RectF rectF = getMatrixRectF();        switch (event.getAction()){            case MotionEvent.ACTION_MOVE:                float dx = x - mLastX;                float dy = y - mLastY;                if(!isCanDrag){                    isCanDrag = isCanDrag(dx,dy);                }                if(isCanDrag){                    if(getDrawable() != null){                        isCheckTopAndBottom = isChekLeftAndRight = true;                        //如果宽度小于屏幕宽度,则禁止左右移动                        if(rectF.width() < getWidth()){                            dx = 0;                            isChekLeftAndRight = false;                        }                        //如果高度小于屏幕高度,则禁止上下移动                        if(rectF.right < 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;    }    /**     * 移动时,进行边界判断,主要判断宽或高大于屏幕的     */    private void checkMatrixBounds() {        RectF rectF = getMatrixRectF();        float deltaX = 0,deltaY = 0;        final float viewWidth = getWidth();        final float viewHeight = getHeight();        //判断移动或者缩放后,图片显示是否超出屏幕边界        if(rectF.top > 0 && isCheckTopAndBottom){            deltaY = -rectF.top;        }        if (rectF.bottom <viewHeight && isCheckTopAndBottom){            deltaY = viewHeight - rectF.bottom;        }        if(rectF.left > 0 && isChekLeftAndRight){            deltaX = -rectF.left;        }        if (rectF.right <viewWidth && isChekLeftAndRight){            deltaX = viewWidth - rectF.right;        }        mScaleMatrix.postTranslate(deltaX, deltaY);    }    //是否推动行为    private boolean isCanDrag(float dx,float dy){        return Math.sqrt((dx*dx) + (dy*dy)) >= mTouchSlop;    }    /**     * 获得当前的缩放比例     * @return     */    public float getScale() {        mScaleMatrix.getValues(matrixValues);        return matrixValues[Matrix.MSCALE_X];    }    @Override    protected void onAttachedToWindow() {        super.onAttachedToWindow();        getViewTreeObserver().addOnGlobalLayoutListener(this);    }    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        getViewTreeObserver().removeGlobalOnLayoutListener(this);    }    /**     * 根据当前图片的Matrix获取图片的范围     * @return     */    public RectF getMatrixRectF() {        Matrix matrix = mScaleMatrix;        RectF rectF = new RectF();        Drawable d = getDrawable();        if(d != null){            rectF.set(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());            matrix.mapRect(rectF);        }        return rectF;    }}
0 0
原创粉丝点击