我有以下代码来激活/停用橡皮擦:

public PorterDuffXfermode clear = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
eraseB.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        if (!eraser) {
                            eraser = true;
                            eraseB.setImageResource(R.drawable.erase_on);
                            paint = new Paint(Paint.DITHER_FLAG);
                            paint.setColor(0x00000000);
                            paint.setAlpha(0x00);
                            paint.setXfermode(clear);
                            paint.setStyle(Paint.Style.STROKE);
                            paint.setStrokeJoin(Paint.Join.ROUND);
                            paint.setStrokeCap(Paint.Cap.ROUND);
                            paint.setStrokeWidth(stroke);
                            paintv.setPaint(paint);
                        } else {
                            eraser = false;
                            eraseB.setImageResource(R.drawable.erase);
                            paint = new Paint(Paint.DITHER_FLAG);
                            paint.setDither(true);
                            paint.setXfermode(null);
                            paint.setColor(Color.RED);
                            paint.setStyle(Paint.Style.STROKE);
                            paint.setStrokeJoin(Paint.Join.ROUND);
                            paint.setStrokeCap(Paint.Cap.ROUND);
                            paint.setStrokeWidth(stroke);
                            paintv.setPaint(paint);
                        }
                    }
                });

setpaint来自我的customview:
public void setPaint(Paint paint) {
    this.paint = paint;
    LogService.log("in setPaint", "paint = " + paint);
}

我用的是Ondraw:
canvas.drawPath(mPath, paint);

如果我停用橡皮擦,它将画一条红线,但相反,如果我激活橡皮擦,而不是擦除,它将画一条黑线。我怎样才能解决这个问题

最佳答案

画布不支持擦除,而位图支持。
基本解决方案流程:
创建另一个画布
创建位图
将位图设置为画布

public void init(int width, int height) {
    Log.i(TAG,"init with "+width+"x"+height);
    foreground = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    cacheCanvas = new Canvas();
    cacheCanvas.setBitmap(foreground);
}

记录位图上的触摸,包括画笔和橡皮擦
public boolean onTouchEvent(MotionEvent event) {
    float eventX = event.getX();
    float eventY = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        currentStroke = new Stroke();
        currentStroke.color = paint;
        currentStroke.path.moveTo(eventX, eventY);
        currentStroke.path.lineTo(eventX, eventY);

        synchronized (strokes) {
            strokes.add(currentStroke);
        }
        lastTouchX = eventX;
        lastTouchY = eventY;
        // There is no end point yet, so don't waste cycles invalidating.
        return true;

    case MotionEvent.ACTION_MOVE:
    case MotionEvent.ACTION_UP:
        // Start tracking the dirty region.
        resetDirtyRect(eventX, eventY);

        // When the hardware tracks events faster than they are delivered,
        // the
        // event will contain a history of those skipped points.
        int historySize = event.getHistorySize();
        for (int i = 0; i < historySize; i++) {
            float historicalX = event.getHistoricalX(i);
            float historicalY = event.getHistoricalY(i);
        expandDirtyRect(historicalX, historicalY);
            if (i == 0) {
                lastX = historicalX;
                lastY = historicalY;
                currentStroke.path.lineTo(historicalX, historicalY);
            } else {
                currentStroke.path.quadTo(lastX, lastY,
                    (historicalX + lastX) / 2,
                    (historicalY + lastY) / 2);
            }
        }

    // After replaying history, connect the line to the touch point.
        if(historySize==0){
            long duration=event.getEventTime()-event.getDownTime();
            float offset=0.1f;
            if(duration<300){
                offset=50.0f/duration;
            }
            currentStroke.path.lineTo(eventX+offset, eventY+offset);
        }else{
            currentStroke.path.lineTo(eventX, eventY);
        }
        synchronized (strokes) {
            strokes.add(currentStroke);
        }

        break;

    default:
    return false;
    }

// Include half the stroke width to avoid clipping.
    float width = paint.getStrokeWidth() / 2;
    invalidate((int) (dirtyRect.left - width),
        (int) (dirtyRect.top - width), (int) (dirtyRect.right + width),
        (int) (dirtyRect.bottom + width));

    lastTouchX = eventX;
    lastTouchY = eventY;

    return true;
    }

在视图的画布上绘制位图
protected void onDraw(Canvas canvas) {
    synchronized (strokes) {
        if (strokes.size() > 0) {
            for (Stroke s : strokes) {
                cacheCanvas.drawPath(s.path, s.color);
            }
            canvas.drawBitmap(foreground, 0, 0, null);
            strokes.clear();
        }
    }
}

关于android - 绘画 Canvas 中的Android橡皮擦不会删除,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18915003/

10-10 10:06