微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 MotionEvent.MOVE

如何解决如何使用 MotionEvent.MOVE

我有可以放大和缩小的自定义图像视图。但我在 onDraw 方法中有“canvas.drawBitmap”:

@Override
    protected void onDraw(Canvas canvas) {
        // Todo Auto-generated method stub
        super.onDraw(canvas);
        if (isPinShouldbedrawn) {
            Bitmap marker = BitmapFactory.decodeResource(getResources(),R.drawable.ic_pin_raster_64);
            canvas.drawBitmap(marker,lastTouchX,lastTouchY,null);
        }

        isPinShouldbedrawn = false;
    }

在“onTouchEvent”方法中,我可以移动图像:

@SuppressWarnings("deprecation")
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mDetector.onTouchEvent(event)) {
            return true;
        }
        int touchCount = event.getPointerCount();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_1_DOWN:
            case MotionEvent.ACTION_POINTER_2_DOWN:
                if (touchCount >= 2) {
                    float distance = distance(event.getX(0),event.getX(1),event.getY(0),event.getY(1));
                    mPrevdistance = distance;
                    isScaling = true;
                } else {
                    mPrevMoveX = (int) event.getX();
                    mPrevMoveY = (int) event.getY();
                }
            case MotionEvent.ACTION_MOVE:
                if (touchCount >= 2 && isScaling) {
                    float dist = distance(event.getX(0),event.getY(1));
                    float scale = (dist - mPrevdistance) / dispdistance();
                    mPrevdistance = dist;
                    scale += 1;
                    scale = scale * scale;
                    zoomTo(scale,mWidth / 2,mHeight / 2);
                    cutting();
                } else if (!isScaling) {
                    int distanceX = mPrevMoveX - (int) event.getX();
                    int distanceY = mPrevMoveY - (int) event.getY();
                    mPrevMoveX = (int) event.getX();
                    mPrevMoveY = (int) event.getY();
                    mMatrix.postTranslate(-distanceX,-distanceY);
                    cutting();
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_POINTER_2_UP:
                if (event.getPointerCount() <= 1) {
                    isScaling = false;
                }
                break;
        }
        return true;
    }

但是来自 onDraw 的位图不动。如果我试图保存新的位图,它只保存可见区域,之后我根本无法缩放或移动它;保存方法

public void save() {
        Bitmap returnedBitmap = Bitmap.createBitmap(
                getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(returnedBitmap);

        draw(canvas);

        setimageBitmap(returnedBitmap);
    }

如何同步移动和缩放图像添加的位图?请帮忙! 全班:

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

import androidx.appcompat.widget.AppCompatimageView;

import com.signalsense.signalsenseapp.R;

public class ScaleImageView extends AppCompatimageView implements OnTouchListener {

    static final float stroke_WIDTH = 10f;
    static final float HALF_stroke_WIDTH = stroke_WIDTH / 2;
    public static Path path = new Path();
    public static int imageheight,imagewidth;
    private static Matrix mMatrix;
    final RectF dirtyRect = new RectF();
    private final Context mContext;
    private final float MAX_SCALE = 2f;
    private final float[] mMatrixValues = new float[9];
    float lastTouchX;
    float lastTouchY;
    Paint paint = new Paint();
    String TAG = "ScaleImageView";
    private boolean isPinShouldbedrawn = false;
    // display width height.
    private int mWidth;
    private int mHeight;
    private int mIntrinsicWidth;
    private int mIntrinsicHeight;
    private float mScale;
    private float mMinScale;
    private float mPrevdistance;
    private boolean isScaling;
    private int mPrevMoveX;
    private int mPrevMoveY;
    private GestureDetector mDetector;

    public ScaleImageView(Context context,AttributeSet attr) {
        super(context,attr);
        this.mContext = context;
        initialize();
    }

    public ScaleImageView(Context context) {
        super(context);
        this.mContext = context;
        initialize();
    }

    private void resetDirtyRect(float eventX,float eventY) {
        dirtyRect.left = Math.min(lastTouchX,eventX);
        dirtyRect.right = Math.max(lastTouchX,eventX);
        dirtyRect.top = Math.min(lastTouchY,eventY);
        dirtyRect.bottom = Math.max(lastTouchY,eventY);
    }

    @Override
    public void setimageBitmap(Bitmap bm) {
        super.setimageBitmap(bm);
        this.initialize();
    }

    @Override
    public void setimageResource(int resId) {
        super.setimageResource(resId);
        this.initialize();
    }

    private void initialize() {
        this.setScaleType(ScaleType.MATRIX);
        mMatrix = new Matrix();
        Drawable d = getDrawable();

        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.stroke);
        paint.setstrokeJoin(Paint.Join.ROUND);
        paint.setstrokeWidth(stroke_WIDTH);

        if (d != null) {
            mIntrinsicWidth = d.getIntrinsicWidth();
            mIntrinsicHeight = d.getIntrinsicHeight();
            setonTouchListener(this);
        }
        mDetector = new GestureDetector(mContext,new GestureDetector.SimpleOnGestureListener() {
                    @Override
                    public boolean onDoubleTap(MotionEvent e) {
                        maxZoomTo((int) e.getX(),(int) e.getY());
                        cutting();
                        return super.onDoubleTap(e);
                    }

                    @Override
                    public void onLongPress(MotionEvent e) {
                        super.onLongPress(e);
                        lastTouchX = e.getX();
                        lastTouchY = e.getY();

                        isPinShouldbedrawn = true;

                        invalidate();
                        save();
                    }
                });

    }

    @Override
    protected boolean setFrame(int l,int t,int r,int b) {
        mWidth = r - l;
        mHeight = b - t;

        mMatrix.reset();
        int r_norm = r - l;
        mScale = (float) r_norm / (float) mIntrinsicWidth;

        int paddingHeight = 0;
        int paddingWidth = 0;
        // scaling vertical
        if (mScale * mIntrinsicHeight > mHeight) {
            mScale = (float) mHeight / (float) mIntrinsicHeight;
            mMatrix.postScale(mScale,mScale);
            paddingWidth = (r - mWidth) / 2;
            paddingHeight = 0;
            // scaling horizontal
        } else {
            mMatrix.postScale(mScale,mScale);
            paddingHeight = (b - mHeight) / 2;
            paddingWidth = 0;
        }
        mMatrix.postTranslate(paddingWidth,paddingHeight);

        setimageMatrix(mMatrix);
        mMinScale = mScale;
        zoomTo(mScale,mHeight / 2);
        cutting();
        return super.setFrame(l,t,r,b);
    }

    protected float getValue(Matrix matrix,int whichValue) {
        matrix.getValues(mMatrixValues);
        return mMatrixValues[whichValue];
    }

    protected float getScale() {
        return getValue(mMatrix,Matrix.MSCALE_X);
    }

    public float getTranslateX() {
        return getValue(mMatrix,Matrix.MTRANS_X);
    }

    protected float getTranslateY() {
        return getValue(mMatrix,Matrix.MTRANS_Y);
    }

    protected void maxZoomTo(int x,int y) {
        if (mMinScale != getScale() && (getScale() - mMinScale) > 0.1f) {
            // threshold 0.1f
            float scale = mMinScale / getScale();
            zoomTo(scale,x,y);
        } else {
            float scale = MAX_SCALE / getScale();
            zoomTo(scale,y);
        }
    }

    public void zoomTo(float scale,int x,int y) {
        if (getScale() * scale < mMinScale) {
            return;
        }
        if (scale >= 1 && getScale() * scale > MAX_SCALE) {
            return;
        }
        mMatrix.postScale(scale,scale);
        // move to center
        mMatrix.postTranslate(-(mWidth * scale - mWidth) / 2,-(mHeight * scale - mHeight) / 2);

        // move x and y distance
        mMatrix.postTranslate(-(x - (mWidth / 2)) * scale,0);
        mMatrix.postTranslate(0,-(y - (mHeight / 2)) * scale);
        setimageMatrix(mMatrix);
    }

    public void cutting() {
        int width = (int) (mIntrinsicWidth * getScale());
        int height = (int) (mIntrinsicHeight * getScale());

        imagewidth = width;
        imageheight = height;

        if (getTranslateX() < -(width - mWidth)) {
            mMatrix.postTranslate(-(getTranslateX() + width - mWidth),0);
        }
        if (getTranslateX() > 0) {
            mMatrix.postTranslate(-getTranslateX(),0);
        }
        if (getTranslateY() < -(height - mHeight)) {
            mMatrix.postTranslate(0,-(getTranslateY() + height - mHeight));
        }
        if (getTranslateY() > 0) {
            mMatrix.postTranslate(0,-getTranslateY());
        }
        if (width < mWidth) {
            mMatrix.postTranslate((mWidth - width) / 2,0);
        }
        if (height < mHeight) {
            mMatrix.postTranslate(0,(mHeight - height) / 2);
        }
        setimageMatrix(mMatrix);
    }

    private float distance(float x0,float x1,float y0,float y1) {
        float x = x0 - x1;
        float y = y0 - y1;
        return (float) Math.sqrt(x * x + y * y);
    }

    private float dispdistance() {
        return (float) Math.sqrt(mWidth * mWidth + mHeight * mHeight);
    }

    public void clear() {
        path.reset();
        invalidate();
    }

    public void save() {
        Bitmap returnedBitmap = Bitmap.createBitmap(
                getWidth(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(returnedBitmap);

        draw(canvas);

        setimageBitmap(returnedBitmap);
    }

    @SuppressWarnings("deprecation")
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mDetector.onTouchEvent(event)) {
            return true;
        }
        int touchCount = event.getPointerCount();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_1_DOWN:
            case MotionEvent.ACTION_POINTER_2_DOWN:
                if (touchCount >= 2) {
                    float distance = distance(event.getX(0),-distanceY);
                    cutting();
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_POINTER_2_UP:
                if (event.getPointerCount() <= 1) {
                    isScaling = false;
                }
                break;
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Todo Auto-generated method stub
        super.onDraw(canvas);
        if (isPinShouldbedrawn) {
            Bitmap marker = BitmapFactory.decodeResource(getResources(),null);
        }

        isPinShouldbedrawn = false;
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View v,MotionEvent event) {
        return super.onTouchEvent(event);
    }

}

对不起,英语不是我的母语:)

解决方法

记录触摸事件的标准化坐标,

public void onLongPress(MotionEvent e) {
    super.onLongPress(e);

    //lastTouchX = e.getX();
    //lastTouchY = e.getY();
    
    float[] touchCoords = new float[]{ e.getX(),e.getY()}; // Touch point in screen-X,Y coords.
    
    Matrix matrix_inverse = new Matrix();
    mMatrix.invert(matrix_inverse); // XY to UV mapping matrix.

    matrix_inverse.mapPoints(touchCoords); // Touch point in bitmap-U,V coords.

    lastTouchX = touchCoords[0];
    lastTouchY = touchCoords[1];

    isPinShouldBeDrawn = true;

    invalidate();
    save();
}

然后,通过应用变换绘制叠加位图。

protected void onDraw(Canvas canvas)
{
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    if (isPinShouldBeDrawn)
    {
        Bitmap marker = BitmapFactory.decodeResource(getResources(),R.drawable.ic_pin_raster_64);

        //canvas.drawBitmap(marker,lastTouchX,lastTouchY,null);

        Matrix matrix_marker = new Matrix();
        matrix_marker.setTranslate(lastTouchX,lastTouchY);
        matrix_marker.postConcat(mMatrix);

        canvas.drawBitmap(marker,matrix_marker,null);
    }
    isPinShouldBeDrawn = false;
}

如果您想将叠加层烘焙到位图上,请将反转矩阵设置为画布并调用 draw()。

public void save()
{
    Bitmap returnedBitmap = Bitmap.createBitmap(
            mIntrinsicWidth,mIntrinsicHeight,Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(returnedBitmap);
    Matrix matrix_inverse = new Matrix();
    mMatrix.invert(matrix_inverse);
    canvas.setMatrix(matrix_inverse);
    draw(canvas);

    setImageBitmap(returnedBitmap);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。