Canvas Eraser正在画一条黑线

Jam*_*oke 7 android android-canvas eraser

我搜索了这个问题并提出了各种解决方案.
但是,没有一个对我有用.

我在应用程序中有一个绘图画布.
画布的背景设置为活动中的png图像,该图像使用自定义视图(drawView);

Bundle extras = intent.getExtras();
    if (extras != null) {
        if (extras.containsKey("background")) {

            //set the background to the resource in the extras
            int imageResource = intent.getIntExtra("background",-1);
            Drawable image = getResources().getDrawable(imageResource);
            drawView.setBackground(image);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在DrawingView类(drawview是实例)中,我存储了PathPaints集合中绘制的路径,它具有3个属性(路径,使用的绘制以及是否为橡皮擦);

private ArrayList<PathPaint> paths = new ArrayList<PathPaint>();
Run Code Online (Sandbox Code Playgroud)

然后我尝试在OnDraw中循环遍历这些路径,并每次使用它们绘制的颜料(多种颜色)重绘它们;

protected void onDraw(Canvas canvas) {

    //if the drawing is new - dont draw any paths
    if (isNew != true) {

        //go through every previous path and draw them
        for (PathPaint p : paths) {

            if (!p.isErase)
            {
                canvas.drawPath(p.myPath, p.myPaint);
            }
            else
            {
                //Paint eraserPaint = setDefaultPaint();
                //eraserPaint.setAlpha(0xFF);
                //eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                //eraserPaint.setColor(Color.TRANSPARENT);
                //canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
                canvas.drawPath(p.myPath, p.myPaint);
            }
            canvas.drawBitmap(canvasBitmap, 0, 0, null);

        }
    }
Run Code Online (Sandbox Code Playgroud)

我在网上尝试了很多提议的选项,但无济于事.

我已经尝试在drawpath上设置绘画以设置所有各种注释掉的属性.

我尝试绘制位图,然后将该位图加载到画布上(canvas.drawBitmap(canvasBitmap,0,0,null))

我在这个类的构造函数中关闭了硬件加速

setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Run Code Online (Sandbox Code Playgroud)

但要么没有绘制线条,要么当集合重绘路径时,橡皮擦会画一条黑线;

在此输入图像描述

有趣的是,如果我使用没有循环方面的位图执行擦除 - 橡皮擦按预期工作;

//If we are making a new drawing we don't want to go through all the paths
    if (isNew != true && erase ==false) {

        //go through every previous path and draw them


        for (PathPaint p : paths) {

            if (!p.isErase)
            {
                canvas.drawPath(p.myPath, p.myPaint);
            }
            //this section now takes place in the elseIF
            else
            {
                Paint eraserPaint = setDefaultPaint();
                eraserPaint.setAlpha(0xFF);
                eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                eraserPaint.setColor(Color.TRANSPARENT);


                canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
                canvas.drawPath(p.myPath, p.myPaint);
            }
        }
    }
    else if (isNew != true && erase ==true)
    {   
        //This works correctly for Erasing but I dont have the ability to Undo/Redo with this approach! 
        canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
        canvas.drawPath(drawPath, drawPaint);

    }
Run Code Online (Sandbox Code Playgroud)

然而,这是一个问题,因为我希望能够撤消/重做擦除(因此集合点)

谁能帮帮我吗?

Kaa*_*mel 3

看起来您只使用一个视图(图层),首先在其中放置背景图像,然后绘制路径,以替换背景。如果是这样,当您擦除时,您将从该唯一的视图/图层中删除,其中包括路径和背景。如果您使用两层(框架布局内的两个视图),一层位于后面,用于加载背景,一层位于前面,用于放置所有路径,那么在顶层上擦除只会删除路径,背景将被删除。通过。

有不同的分层方法。例如,此 FrameLayout 替换了当前保存背景和绘制路径的视图(在代码中指的是 XXXView)。

<FrameLayout
   android:layout_width= ...copy from the existing XXXView ...
   android:layout_height= ...copy from the existing XXXView ... >

   <ImageView 
      android:id = "@+id/background"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      ...
      ... the background is loaded here />


   <XXXView (this the existing view where the paths are drawn onto)
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      ...
      ... no background here />

</FrameLayout>
Run Code Online (Sandbox Code Playgroud)