Android图片处理总结四:双击图片,保持点击位置不变放大

双击ImageView,需要保持图片点击点相对布局的位置不变,然后放大图片,因为项目大量的ImageView都需要这个功能,所以扩展了ImageView。主要是:
1.扩展ImageView类
2.重写手势控制类GestureDetector.SimpleOnGestureListener 中的onDoubleTap()方法
3.利用Matrix进行放大和平移图片
详细代码如下,有详细注释:

//扩展ImageView类
public class ScaleImageView extends ImageView{
    private Drawable nullDrawable;
    //定义手势控制类
    private GestureDetectorCompat mDetector;
    private float initX,initY;
    private Matrix matrix;
    private float defaultScale = 1.0f;
        private float preScaleX = 1.0f,preScaleY = 1.0f;
    public LocalImageView(Context context) {
        super(context);
    }

    public ScaleImageView (Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public ScaleImageView (Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }



    private void init(Context context, AttributeSet attrs)
    {
        nullDrawable = null;
        if(attrs != null) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ImageStyle);

            nullDrawable = typedArray.getDrawable(R.styleable.ImageStyle_nullDrawable);
            typedArray.recycle();

        }
        mDetector = new GestureDetectorCompat(context, new MyGestureListener());
        matrix = new Matrix();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if(nullDrawable != null)
            nullDrawable.setBounds((getWidth() - nullDrawable.getIntrinsicWidth())/2,(getHeight() - nullDrawable.getMinimumHeight())/2,(getWidth() - nullDrawable.getIntrinsicWidth())/2+ nullDrawable.getIntrinsicWidth(),(getHeight() - nullDrawable.getMinimumHeight())/2 + nullDrawable.getMinimumHeight());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if(this.getDrawable() == null) {
            canvas.drawColor(getResources().getColor(R.color.clr_grey));
            if (nullDrawable != null)
                nullDrawable.draw(canvas);
        }
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        //使用手势控制类处理MotionEvent 
        mDetector.onTouchEvent(event);
        return true;
    }
    //扩展GestureDetector.SimpleOnGestureListener类
    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        //重写onDoubleTap方法
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            //获取双击坐标
            float clickX = e.getX();
            float clickY = e.getY();

            //H获取上一次的方法系数
           float oldScale = getScale();
           //每次双击放大倍数加0.1
            float scale = oldScale + 0.1f;

            //获取上一次的平移量,
            float oldTranX = -getTranX();
            float oldTranY = -getTranY();

            //设置放大系数
            matrix.setScale(scale,scale);

           /*
            计算新的平移量:
            1.算出点击点相对于目前图片的坐标:
                clickX和clickY是点击坐标,相对于图片(已经被放大)的坐标需要加上平移量clickX + oldTranX
            2.算出点击点相对于原图片的坐标(注意是原始图片):
                (clickX + oldTranX)/oldScale 
            3.算出此次放大,点击点相对于放大图片的坐标(注意是放大后的图片):
                ((clickX + oldTranX)/oldScale)*scale
            4..计算新的平移量:
                ((clickX + oldTranX)/oldScale)*scale - clickX
             */
            float tranX  = -(((clickX - oldTranX)/oldScale)*scale - clickX);
            float tranY  = -(((clickY - oldTranY)/oldScale)*scale - clickY);
            //设置平移,因为是要向左和向上平移,所以是负数
            matrix.postTranslate(-tranX,-tranY);
            //设置矩阵
            setImageMatrix(matrix);
            return super.onDoubleTap(e);
        }
    }
    public float getScale()
    {
        float[] values = new float[9];
        matrix.getValues(values);
        return values[Matrix.MSCALE_X];
    }

    public float getTranX()
    {
        float[] values = new float[9];
        matrix.getValues(values);
        return values[Matrix.MTRANS_X];
    }

    public float getTranY()
    {
        float[] values = new float[9];
        matrix.getValues(values);
        return values[Matrix.MTRANS_Y];
    }

你可能感兴趣的:(android)