android 两指缩放图片 event.getActionMasked() 方法的使用

想实现一个缩放图片的效果,是那种两指触摸滑动缩放的。我并没有去重新ImageView 而是重写了View然后 调用canvas.drawBitmap的方法,然后通过matrix去实现缩放效果的。(重写ImageView会更麻烦的)这里的实现比较简单。

代码如下:

public class ScaleImage extends BaseView {

    private Matrix matrix;
    private Bitmap bitmap;
    private Paint paint;

    private int fingerSize = 0;
    private float downX0;
    private float downY0;
    private float downX1;
    private float downY1;

    public ScaleImage(Context context) {
        super(context);
    }

    public ScaleImage(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ScaleImage(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public ScaleImage(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        paint = new Paint();
        paint.setAntiAlias(true);
        matrix = new Matrix();
        Bitmap temp = BitmapFactory.decodeResource(getResources(), R.drawable.yellow);
        int bw = temp.getWidth();
        int bh = temp.getHeight();
        float scale = Math.min(1f * mWidth / bw, 1f * mHeight / bh);
        LogUtils.w("scale==" + scale);
        bitmap = scaleBitmap(temp, scale);
        // compute init left, top
        int bbw = bitmap.getWidth();
        int bbh = bitmap.getHeight();
        Point center = new Point(mWidth / 2, mHeight / 2);
        Point bmpCenter = new Point(bbw / 2, bbh / 2); // 图片原来的中心点
//        matrix.postScale(0.9f, 0.9f, center.x, center.y); // 中心点参数是有用的
        matrix.postTranslate(center.x - bmpCenter.x, center.y - bmpCenter.y); // 移动到当前view 的中心
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(bitmap, matrix, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // todo: event.getPointerCount() 这个值并不准确,第一个离开的手指没有去计算!
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                fingerSize = 1;
                LogUtils.i("当前手指数量:" + fingerSize);
                downX0 = event.getX(0);
                downY0 = event.getY(0);
                break;
            case MotionEvent.ACTION_MOVE:
                if (fingerSize >= 2) {
                    // 计算两指触摸到的时候,中心点的位置
                    float center2x = downX0 + (downX1 - downX0) / 2;
                    float center2y = downX0 + (downX1 - downX0) / 2;
                    float x0 = event.getX(0);
                    float y0 = event.getY(0);
                    float x1 = event.getX(1);
                    float y1 = event.getY(1);

                    // 缩放比例:移动后的两点距离 / 移动前的两点距离
                    float scaleX = distance(x0, y0, x1, y1) / distance(downX0, downY0, downX1, downY1);
                    LogUtils.w("缩放比例:" + scaleX);
                    if (Math.abs(scaleX) <= 2) {
                        matrix.postScale(scaleX, scaleX, center2x, center2y);
                    }
                    downX0 = x0;
                    downY0 = y0;
                    downX1 = x1;
                    downY1 = y1;
                } else if (fingerSize == 1) {
                    // 移动图片
                    float x0 = event.getX(0);
                    float y0 = event.getY(0);
                    float dx = x0 - downX0;
                    float dy = y0 - downY0;
                    matrix.postTranslate(dx, dy);
                    downX0 = x0;
                    downY0 = y0;
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                fingerSize += 1;
                LogUtils.i("当前手指数量:" + event.getPointerCount());
                if (fingerSize == 2) {
                    downX1 = event.getX(0);
                    downY1 = event.getY(0);
                }

                break;
            case MotionEvent.ACTION_POINTER_UP:
                fingerSize -= 1;
                LogUtils.i("当前手指数量:" + event.getPointerCount());
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
            case MotionEvent.ACTION_UP:
                fingerSize = 0;
                LogUtils.i("当前手指数量:" + event.getPointerCount());
                break;
        }
        postInvalidate();
        return true;
    }

    private float distance(float x1, float y1, float x2, float y2) {

        float dx = x2 - x1;
        float dy = y2 - y1;

        return (float) Math.pow(dx * dx + dy * dy, 0.5);
    }

    /**
     * 根据给定的宽和高进行拉伸
     *
     * @param origin 原图
     * @param scale  缩放比例
     * @return new Bitmap
     */
    private Bitmap scaleBitmap(Bitmap origin, float scale) {
        if (origin == null) {
            return null;
        }
        int height = origin.getHeight();
        int width = origin.getWidth();
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);// 使用后乘
        Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
        if (!origin.isRecycled()) {
            origin.recycle();
        }
        return newBM;
    }
}

由于这个需要动图才能看到效果,我就不上图了。

以上,就实现了单指移动,双指缩放的效果了。~


参考资料:
安卓–多指触控
getAction、getActionMask、getActionIndex区别
安卓开发——MotionEvent中getAction、getActionMask、getActionIndex区别

猜你喜欢

转载自blog.csdn.net/DucklikeJAVA/article/details/80968127
今日推荐