代码之家  ›  专栏  ›  技术社区  ›  rosu alin

带有PorterDuff.Mode.CLEAR的橡皮擦总是在我想删除的地方画一条黑线

  •  4
  • rosu alin  · 技术社区  · 11 年前

    我可以让它画出路径吗?我可以用透明线移动手指删除路径,或者根本不画?

    这就是我实例化橡皮擦的方式:

     OnClickListener eraseListener = new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                mPaint.setColor(0x00000000);
                mPaint.setXfermode(clear);
                mPaint.setAlpha(0x00);
                myView.setPaint(mPaint);
                LogService.log("PaintActivity", "------in eraseListener");
    
            }
        };
    

    这将从包含画布的“视图”中设置绘画。 这里我有以下动作事件:

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    private void touch_move(float x, float y) {
        float dx, dy;
            dx = Math.abs(x - mX);
            dy = Math.abs(y - mY);
        if ((dx >= TOUCH_TOLERANCE) || (dy >= TOUCH_TOLERANCE)) {
            undoPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
                mX = x;
                mY = y;
        }
    }
    private void touch_up() {
        mPath.lineTo(mX, mY);
        mPath.moveTo(mX, mY);
        canvas.drawPath(mPath, paint);
        mPath.reset();
    }
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touch_start(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            touch_move(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touch_up();
            invalidate();
            break;
        }
        return true;
    }
    

    现在,如果我想擦除,正如我所说,当我移动手指时,它会在路径上画一条黑线。当我把手指取下时,在touch_up上,它会擦除它画的黑线后面的内容。如果我评论invalidate();从touch_move函数中选择一条黑线,那么它不会画出那条黑线,而且,它只会在touch_up上擦除。我不能让它实时擦除吗?

    4 回复  |  直到 11 年前
        1
  •  11
  •   andyg0808 Lou Franco    11 年前

    我是这样解决的:

    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
    
            mPath.lineTo(mX, mY);
            // commit the path to our offscreen
            mCanvas.drawPath(mPath, mPaint);
            mPath.reset();
            mPath.moveTo(mX, mY);
    
            mX = x;
            mY = y;
        }
    }
    

    在这里,我在路径上添加了一条线,绘制了路径,重置了路径,并使用 moveTo touch_move 方法

    在…上 touch_up 我只使用 mPath.reset() .

    private void touch_up() {
    
        // kill this so we don't double draw
         mPath.reset();
    
    }
    

    这使我的橡皮擦透明,擦除时没有黑线。

        2
  •  8
  •   sithmal_    10 年前

    只需关闭HWA。

    或者您可以在构造函数中添加此行

    setLayerType(View.LAYER_TYPE_SOFTWARE, mPaint);
    
        3
  •  4
  •   vals    10 年前

    要在没有黑线的情况下擦除,请在onDraw()中修改代码:

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        if (mMode != PAINT_MODE) {
            return;
        }
        canvas.drawPath(mPath, mPaint);
    }
    

    如果你想让手指擦除更自然,可以修改touch_move()的代码

    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
        mX = x;
        mY = y;
        if (mMode != PAINT_MODE) {
            mCanvas.drawPath(mPath, mPaint);
        }
    
        4
  •  0
  •   Vladimir Vagaytsev    8 年前

    在画布上绘制原始位图之前,只需再绘制一个相同大小的透明位图。

    Bitmap b = Bitmap.createBitmap(orgBM.getWidth(), orgBM.getHeight(), Bitmap.Config.ARGB_8888);
    
    Canvas c = new Canvas();
    c.setBitmap(b);
    
    c.drawBitmap(orgBM, 0, 0, null);