我有一个适用于Android的绘图应用程序,目前正在尝试向其中添加一个真实的橡皮擦。以前,我只是将白色涂料用作橡皮擦,但是现在不再使用,因为现在我可以使用背景色和图像了。我通过在透明 Canvas 下面有一个 ImageView 来实现此目的。

我面临的问题是,每当启用橡皮擦时,只要我放下手指,它就会绘制一条黑色实线,但是一旦松开,它就会变成透明的。请参见下面的屏幕截图:

这是我的手指在屏幕上时的外观-黑色实线

这是我从屏幕上移开手指后的样子

因此,似乎我接近了,但是我找不到正确的设置组合来避免在擦除时手指触摸时出现黑迹。以下是一些相关的代码段:

onDraw

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.TRANSPARENT);
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    canvas.drawPath(mPath, mPaint);
    canvas.drawPath(mPreviewPath, mPaint);
}

onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event) {
    float currentX = event.getX();
    float currentY = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touchStart(currentX, currentY);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touchMove(currentX, currentY);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touchUp(currentX, currentY);
            invalidate();
            break;
    }
    return true;
}

当前尝试设置橡皮擦
public void startEraser() {
    mPaint.setAlpha(0);
    mColor = Color.TRANSPARENT;
    mPaint.setColor(Color.TRANSPARENT);
    mPaint.setStrokeWidth(mBrushSize);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setMaskFilter(null);
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    mPaint.setAntiAlias(true);
}

关于橡皮擦还有其他几篇文章,但是其中大多数只是说要使用PorterDuff.Mode.CLEARsetMakFilter(null),并且应该可以使用。就我而言,事实并非如此。不管我尝试什么,我都会先得到黑色的痕迹,然后再释放后才得到所需的结果。

如果需要,我可以提供更多代码。

最佳答案

我建议您阅读FingerPaint.java的官方样本
它与您要在此处实现的目标完全匹配。

要在删除内容时不显示路径,请查看onDraw()方法和eraserMode变量:

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(0xFFAAAAAA);
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    if (!eraserMode) {
        canvas.drawPath(mPath, mPaint);
    }
}

boolean eraserMode = false;

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    eraserMode = false;
    mPaint.setXfermode(null);
    mPaint.setAlpha(0xFF);
    switch (item.getItemId()) {
        /*...*/
        case ERASE_MENU_ID:
            // Add this line
            eraserMode = true;
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            return true;
        /*...*/
    }
    return super.onOptionsItemSelected(item);
}

10-08 03:09