java - 如何在触摸事件上绘制矩形

标签 java android android-canvas

如何在android中的触摸事件上绘制矩形。当我触摸 Canvas 时,我有一个 Canvas ,它绘制一个矩形,但是当我触摸新位置时,它会删除旧矩形并在新位置绘制一个新矩形。但是,我想让所有矩形在我触摸过的地方都可见。

public class TouchImageView extends ImageView {

    Matrix matrix = new Matrix();

    // We can be in one of these 3 states

    static final int NONE = 0;

    static final int DRAG = 1;

    static final int ZOOM = 2;

    boolean isCheckLoadImage = false;

    public static boolean isDraw = false;

    int mode = NONE;

    private float mPosX;

    private float mPosY;

    public static int numCell1 = 0;

    public static boolean CorrectTouch;

    float boxHeight, boxWidth;

    // Remember some things for zooming

    PointF last = new PointF();

    PointF start = new PointF();

    float minScale = 1f;

    float maxScale = 6f;

    int lastTouchEvent = -1;

    int selectedCell;

    float[] m;

    float scaleWidth, scaleHeight;

    float redundantXSpace, redundantYSpace;

    float width, height;

    static final int CLICK = 3;

    float saveScale = 1f;

    float right, bottom, origWidth, origHeight, bmWidth, bmHeight;

    ScaleGestureDetector mScaleDetector;

    Context context;

    boolean flag = false;


    public TouchImageView(Context context) {

        super(context);

        sharedConstructing(context);

    }

    public TouchImageView(Context context, AttributeSet attrs) {

        super(context, attrs);

        sharedConstructing(context);

    }

    @Override
    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        Paint paint = new Paint();

        paint.setColor(Color.RED);

        paint.setStyle(Paint.Style.STROKE);

        paint.setStrokeWidth(4);

        RectF r = new RectF();

        matrix.mapRect(r);

        boxWidth = scaleWidth / 5;

        boxHeight = scaleHeight / 5;

        float widthOfCell = boxWidth;

        float heightOfCell = boxHeight;

        float[] touchPoint = new float[] { mPosX, mPosY };

        float[] newTouch = new float[] { 0, 0 };

        matrix.mapPoints(newTouch, touchPoint);

        RectF canvasRect = new RectF();

        canvas.getMatrix().mapRect(canvasRect);

        Log.i("canvasRect", "canvasRect.left : " + canvasRect.left
                + " canvasRect.top : " + canvasRect.top);

        Log.i("r", "r.left : " + r.left + " r.top : " + r.top);

        Log.i("Pos", "mPosX : " + mPosX + " mPosY : " + mPosY);

        float newX = mPosX - (r.left);

        float newY = mPosY - (r.top);

        Log.i("new XY", "New X" + newX + " NewY " + newY);

        int myX = (int) (newX / boxWidth); /* Columns */

        int myY = (int) (newY / boxHeight);/* Rows */

        Log.i("my XY", "myX " + myX + " myY " + myY);

        //

        Log.e("GuessImageView", "before grid draw");

        try {

            if (true) {

                if (lastTouchEvent == MotionEvent.ACTION_UP) {

                    numCell1 = 0;

                    boolean doBreak = false;

                    for (float row = 0; !doBreak
                            && row <5; row++) {

                        float y = (row * heightOfCell) + r.top;

                        for (float col = 0; col < 5; col++) {

                            float x = (col * widthOfCell) + r.left;

                            if ((int) col == myX && (int) row == myY) {

                                canvas.drawRect(x, y, x + widthOfCell, y
                                        + heightOfCell, paint);

                                Log.d("Touch X : " + x, "Touch Y : " + y);

                                selectedCell = numCell1;

                                numCell1++;

                                flag = true;

                                doBreak = true;

                                break;

                            }

                            numCell1++;

                        }

                    }

                    if (flag) {

                        isCheckLoadImage = true;

//                      guessImage.checkForWin(selectedCell);

                    }

                    Log.i("Touch ", "Number Of Cell>" + numCell1);

                    lastTouchEvent = -1;

                }

            }

        } catch (ArithmeticException e) {

            e.printStackTrace();

        }

        Log.e("GuessImageView", "after grid draw");

    }

    private void sharedConstructing(Context context) {

        super.setClickable(true);

        this.context = context;

        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());

        matrix.setTranslate(1f, 1f);

        m = new float[9];

        setImageMatrix(matrix);

        setScaleType(ScaleType.MATRIX);

        setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                mScaleDetector.onTouchEvent(event);

                matrix.getValues(m);

                float x = m[Matrix.MTRANS_X];

                float y = m[Matrix.MTRANS_Y];

                PointF curr = new PointF(event.getX(), event.getY());

                switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:

                    last.set(event.getX(), event.getY());

                    start.set(last);

                    mode = DRAG;

                    // isDraw=false;

                    break;

                case MotionEvent.ACTION_MOVE:

                    // Log.i("onTouch", "origWidth : " + origWidth +

                    // " origHeight : " + origHeight);

                    if (mode == DRAG) {

                        // isDraw=false;

                        float deltaX = curr.x - last.x;

                        float deltaY = curr.y - last.y;

                        scaleWidth = Math.round(origWidth * saveScale);

                        scaleHeight = Math.round(origHeight * saveScale);

                        if (scaleWidth < width) {

                            deltaX = 0;

                            if (y + deltaY > 0)

                                deltaY = -y;

                            else if (y + deltaY < -bottom)

                                deltaY = -(y + bottom);

                        } else if (scaleHeight < height) {

                            deltaY = 0;

                            if (x + deltaX > 0)

                                deltaX = -x;

                            else if (x + deltaX < -right)

                                deltaX = -(x + right);

                        } else {

                            if (x + deltaX > 0)

                                deltaX = -x;

                            else if (x + deltaX < -right)

                                deltaX = -(x + right);

                            if (y + deltaY > 0)

                                deltaY = -y;

                            else if (y + deltaY < -bottom)

                                deltaY = -(y + bottom);

                        }

                        matrix.postTranslate(deltaX, deltaY);

                        last.set(curr.x, curr.y);

                    }

                    break;

                case MotionEvent.ACTION_UP: {

                    mode = NONE;

                    int xDiff = (int) Math.abs(curr.x - start.x);

                    int yDiff = (int) Math.abs(curr.y - start.y);

                    if (xDiff < CLICK && yDiff < CLICK) {

                        // isDraw=false;

                        Log.v("ACTION_UP", "ACTION_UP");

                        mPosX = curr.x;

                        mPosY = curr.y;

                        performClick();

//                      if (guessImage.guess_mode) {

                            lastTouchEvent = event.getAction();
                        /*}

                        else {

                            lastTouchEvent = -1;

                        }
*/
                        // invalidate();

                    }

                    break;

                }

                case MotionEvent.ACTION_POINTER_UP:

                    mode = NONE;

                    break;

                }

                setImageMatrix(matrix);

                scaleWidth = Math.round(origWidth * saveScale);

                scaleHeight = Math.round(origHeight * saveScale);

                invalidate();

                return true; // indicate event was handled

            }

        });

    }

    @Override
    public void setImageBitmap(Bitmap bm) {

        super.setImageBitmap(bm);

        if (bm != null) {

            bmWidth = bm.getWidth();

            bmHeight = bm.getHeight();

        }

    }

    public void setMaxZoom(float x) {

        maxScale = x;

    }

    private class ScaleListener extends
            ScaleGestureDetector.SimpleOnScaleGestureListener {

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {

            mode = ZOOM;

            return true;

        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {

            float mScaleFactor = detector.getScaleFactor();

            float origScale = saveScale;

            saveScale *= mScaleFactor;

            if (saveScale > maxScale) {

                saveScale = maxScale;

                mScaleFactor = maxScale / origScale;

            } else if (saveScale < minScale) {

                saveScale = minScale;

                mScaleFactor = minScale / origScale;

            }

            right = width * saveScale - width
                    - (2 * redundantXSpace * saveScale);

            bottom = height * saveScale - height
                    - (2 * redundantYSpace * saveScale);

            // mPosX = mPosX + right / saveScale;

            // mPosY = mPosY + bottom / saveScale;

            if (origWidth * saveScale <= width
                    || origHeight * saveScale <= height) {

                float xMove = 0, yMove = 0;

                matrix.postScale(mScaleFactor, mScaleFactor, width / 2,
                        height / 2);

                if (mScaleFactor < 1) {

                    matrix.getValues(m);

                    float x = m[Matrix.MTRANS_X];

                    float y = m[Matrix.MTRANS_Y];

                    if (mScaleFactor < 1) {

                        if (Math.round(origWidth * saveScale) < width) {

                            if (y < -bottom) {

                                matrix.postTranslate(0, -(y + bottom));

                                xMove = 0;

                                yMove = -(y + bottom);

                            } else if (y > 0) {

                                matrix.postTranslate(0, -y);

                                xMove = 0;

                                yMove = -y;

                            }

                        } else {

                            if (x < -right) {

                                matrix.postTranslate(-(x + right), 0);

                                xMove = -(x + right);

                                yMove = 0;

                            } else if (x > 0) {

                                matrix.postTranslate(-x, 0);

                                xMove = -(x + right);

                                yMove = 0;

                            }

                        }

                        Log.i("onScale", "mPosX " + mPosX + " mPosX " + mPosX);

                    }

                }

            } else {

                float xMove = 0, yMove = 0;

                matrix.postScale(mScaleFactor, mScaleFactor,
                        detector.getFocusX(), detector.getFocusY());

                matrix.getValues(m);

                float x = m[Matrix.MTRANS_X];

                float y = m[Matrix.MTRANS_Y];

                if (mScaleFactor < 1) {

                    if (x < -right) {

                        matrix.postTranslate(-(x + right), 0);

                        xMove = -(x + right);

                        yMove = 0;

                    } else if (x > 0) {

                        matrix.postTranslate(-x, 0);

                        xMove = -x;

                        yMove = 0;

                    }

                    if (y < -bottom) {

                        matrix.postTranslate(0, -(y + bottom));

                        xMove = 0;

                        yMove = -(y + bottom);

                    } else if (y > 0) {

                        matrix.postTranslate(0, -y);

                        xMove = 0;

                        yMove = -y;

                    }

                }

                Log.i("onScale", "mPosX " + mPosX + " mPosX " + mPosX);

            }

            return true;

        }

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        if (!isCheckLoadImage) {

            width = MeasureSpec.getSize(widthMeasureSpec);

            height = MeasureSpec.getSize(heightMeasureSpec);

            // Fit to screen.

            float scale;

            float scaleX = (float) width / (float) bmWidth;

            float scaleY = (float) height / (float) bmHeight;

            scale = Math.min(scaleX, scaleY);

            matrix.setScale(scale, scale);

            setImageMatrix(matrix);

            saveScale = 1f;

            // Center the image

            redundantYSpace = (float) height - (scale * (float) bmHeight);

            redundantXSpace = (float) width - (scale * (float) bmWidth);

            redundantYSpace /= (float) 2;

            redundantXSpace /= (float) 2;

            matrix.postTranslate(redundantXSpace, redundantYSpace);

            origWidth = width - 2 * redundantXSpace;

            origHeight = height - 2 * redundantYSpace;

            right = width * saveScale - width
                    - (2 * redundantXSpace * saveScale);

            bottom = height * saveScale - height
                    - (2 * redundantYSpace * saveScale);

            setImageMatrix(matrix);

        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

}

最佳答案

您需要将所有触摸位置存储在内存中,并每次都重新绘制它们。

就像这个示例:Android drawing objects on screen and obtaining geometry data

关于java - 如何在触摸事件上绘制矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13342156/

相关文章:

具有最少随机数的 Java 排列

java.lang.LinkageError : loader constraint violation:previously initiated loading for a different type with name "javax/mail/Session" 错误

android - 拖放在 nhaarman 的 ListviewAnimation 库中不起作用

android - 使 Canvas 透明

java - 使用 Android 操作栏上的按钮调用方法

java - 删除或更改 google-services.json 文件

java - 更改 JFrame 窗口按钮

android - 在Android Studio中构建Unity项目的问题

java - 如何使用 libGDX 在 Android 中加载音乐?

android - 在另一个 Android 上覆盖位图