Android图片双指缩放,单指移动实现

Android 实现,图片双指缩放,单指移动。通过自定义ImageView控件实现。

ZoomDragImageView.java代码如下:



public class SwZoomDragImageView extends ImageView implements View.OnTouchListener{
    private static final String TAG = SwZoomDragImageView.class.getSimpleName();
    private boolean support_touch = true;//支持触摸事件

    private int mode = 0;// 初始状态
    private static final int MODE_DRAG = 1;//平移
    private static final int MODE_ZOOM = 2;//缩放

    private static final float MAX_SCALE = 4f, MIN_SCALE = 1f;//最大放大倍数,最小放大倍数
    float total_scale = MIN_SCALE , current_scale;//total_scale缩放范围2-1,当小于1回弹到1;当大于2回弹到2

    private Matrix matrixNow = new Matrix();
    private Matrix matrixBefore = new Matrix();
    private Matrix mInitializationMatrix = new Matrix();//初始缩放值

    private PointF actionDownPoint = new PointF();//点击点
    private PointF dragPoint = new PointF();//平移点
    private PointF startPoint = new PointF();//滑动点
    private PointF mInitializationScalePoint = new PointF();//初始缩放点
    private PointF mCurrentScalePoint = new PointF(0, 0);//当前缩放点
    private float startDis;//滑动开始距离
    /** 两个手指的中间点 */
    private PointF midPoint = new PointF(0,0);

    public SwZoomDragImageView(Context context) {
        this(context, null);
    }
    public SwZoomDragImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public SwZoomDragImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initData();
    }
    private void initData() {
        if (support_touch) {
            setOnTouchListener(this);
        }
        this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                SwZoomDragImageView.this.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                int[] viewLocation = new int[2];
                SwZoomDragImageView.this.getLocationInWindow(viewLocation);
                int viewX = viewLocation[0]; // x 坐标;有bug,在viewpage中。
                int viewY = viewLocation[1]; // y 坐标
                mInitializationScalePoint.set( SwZoomDragImageView.this.getWidth() / 2, viewY + SwZoomDragImageView.this.getHeight() / 2);//初始化缩放位置
                Log.i("yangxun", "控件 宽:" + mInitializationScalePoint.x + "高:" + mInitializationScalePoint.y);
            }
        });
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);//清空画布
        if (matrixNow != null) {
            canvas.concat(matrixNow);
//            canvas.setMatrix(matrixNow);//显示有问题
        }
        super.onDraw(canvas);
    } @Override
    public void setImageMatrix(Matrix matrix) {
        matrixNow.set(matrix);
        invalidate();
    }


    public void resetImageMatrix() {
        this.matrixNow.set(mInitializationMatrix);
        invalidate();
    }
    //最小重置数值
    private void resetToMinStatus(){
        mCurrentScalePoint.set(0, 0);
        total_scale = MIN_SCALE;
    }
    //最大重置数值
    private void resetToMaxStatus(){
        total_scale = MAX_SCALE;
    }
    public float getInitializationBitmapHeight(){
        return getHeight()*total_scale;
    }
    public float getInitializationBitmapWidth(){
        return getWidth()*total_scale;
    }
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (total_scale != 1) {
            getParent().requestDisallowInterceptTouchEvent(true);//触摸事件请求拦截
        }
        /** 通过与运算保留最后八位 MotionEvent.ACTION_MASK = 255 */
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN://单指触摸
                mode = MODE_DRAG;
                matrixBefore.set(getImageMatrix());
                matrixNow.set(getImageMatrix());
                dragPoint.set(event.getX(), event.getY());
                actionDownPoint.set(event.getX(), event.getY());
                break;

            case MotionEvent.ACTION_POINTER_DOWN://双指触摸
                getParent().requestDisallowInterceptTouchEvent(true);//触摸事件请求拦截
                mode = MODE_ZOOM;
                startPoint.set(event.getX(), event.getY());
                startDis = distance(event);
                /** 计算两个手指间的中间点 */
                if (startDis > 10f) {
                    //记录当前ImageView的缩放倍数
                    matrixBefore.set(getImageMatrix());
                    matrixNow.set(getImageMatrix());
                }
                break;

            case MotionEvent.ACTION_MOVE:
                if (mode == MODE_DRAG && total_scale > 1) {
                    float dx = event.getX() - dragPoint.x;
                    float dy = event.getY() - dragPoint.y;
                    dragPoint.set(event.getX(), event.getY());
                    imgTransport(dx, dy);
                } else if (mode == MODE_ZOOM) {//缩放
                    float endDis = distance(event);
                    midPoint = mid(event);
                    if (endDis > 10f) {
                        current_scale = endDis / startDis;//缩放倍数
                        total_scale *= current_scale;
                        matrixNow.postScale(current_scale, current_scale, midPoint.x, midPoint.y);
                        invalidate();
                    }
                    startDis = endDis;
                }
                break;

            case MotionEvent.ACTION_UP:
                getParent().requestDisallowInterceptTouchEvent(false);//触摸事件请求取消拦截
                mode = 0;
                if(mode == MODE_DRAG)
                    checkClick(event.getX(),event.getY(), actionDownPoint.x, actionDownPoint.y);
                break;

            case MotionEvent.ACTION_POINTER_UP:
                checkZoomValid();
                mode = 0;
                break;

        }
        return true;
    }
    /**
     * 平移图片
     * @param x
     * @param y
     */
    public void imgTransport(float x,float y){
        mCurrentScalePoint.set(mCurrentScalePoint.x + x, mCurrentScalePoint.y + y);
        if (mCurrentScalePoint.x >= ((total_scale - 1) * getWidth()) / 2) {
            mCurrentScalePoint.x = ((total_scale - 1) * getWidth()) / 2;
            x = 0;
        } else {
            if (mCurrentScalePoint.x <= -((total_scale - 1) * getWidth()) / 2) {
                mCurrentScalePoint.x = -((total_scale - 1) * getWidth()) / 2;
                x = 0;
            }
        }
        if (mCurrentScalePoint.y >= ((total_scale - 1) * getHeight()) / 2) {
            mCurrentScalePoint.y = ((total_scale - 1) * getHeight()) / 2;
            y = 0;
        } else {
            if (mCurrentScalePoint.y <= -((total_scale - 1) * getHeight()) / 2) {
                mCurrentScalePoint.y = -((total_scale - 1) * getHeight()) / 2;
                y = 0;
            }
        }
        Log.i(TAG, "mCurrentScalePoint.x:" + mCurrentScalePoint.x + "   x:" + x);
        matrixNow.postTranslate(x, y);
        invalidate();
    }
    private boolean checkZoomValid() {
        if(mode == MODE_ZOOM){
            if(total_scale>MAX_SCALE){
                resetToMaxStatus();
                matrixNow.set(mInitializationMatrix);
                matrixNow.postScale(MAX_SCALE, MAX_SCALE, mInitializationScalePoint.x, mInitializationScalePoint.y);
                matrixNow.postTranslate(mCurrentScalePoint.x, mCurrentScalePoint.y);
                invalidate();
                return false;
            }else if(total_scale

好了,现在直接使用该类,就可以直接对图片进行相应操作。

你可能感兴趣的:(Android)