2016-05-22 11 views
7

Ich habe dieses Problem gegooglet und verschiedene Lösungen vorgeschlagen.
Allerdings funktionierte keiner für mich.Canvas Eraser zeichnet eine schwarze Linie

Ich habe eine Zeichenfläche in einer App.
Der Hintergrund der Zeichenfläche wird auf ein PNG-Bild in der Aktivität gesetzt, die die benutzerdefinierte Ansicht verwendet (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); 
     } 
    } 

Im DrawingView Klasse (drawview ist die Instanz), I speichert die in einer Sammlung von gezogenen PathPaints Pfade, die 3 Eigenschaften (den Pfad, die Farbe verwendet, und wenn es einen Radiergummi);

private ArrayList<PathPaint> paths = new ArrayList<PathPaint>(); 

I versuchen dann durch diese Pfade in OnDraw Schleife und neu zu zeichnen sie jedes Mal mit den Farben, die sie mit (Mutiple Farben) gezogen wurden;

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); 

     } 
    } 

Ich habe viele der vorgeschlagenen Optionen online versucht, aber ohne Erfolg.

Ich habe versucht, die Farbe auf dem Zeichenpfad zu setzen, um alle verschiedenen auskommentierten Eigenschaften einzustellen.

habe ich versucht, auf einem Bitmap-Zeichnung und dann diese Bitmap auf die Leinwand zu laden (canvas.drawBitmap (canvasBitmap, 0, 0, NULL))

I haben die Hardware-Beschleunigung in dieser Klasse ausgeschaltet Konstruktor

aber entweder wird die Linie nicht gezeichnet oder wenn die Sammlung die Pfade neu zeichnet, zeichnet der Radierer eine schwarze Linie;

enter image description here

Interessant ist, dass, wenn ich das Löschen mit der Bitmap ohne die Schleife Aspekt durchführen - der Radiergummi wie erwartet funktioniert; Diese

//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); 

    } 

ist jedoch ein Problem, da ich möchte in der Lage sein, um Undo/Redo Löschen (also den Punkt der Sammlung)

Kann jemand mir bitte helfen?

+0

drawView.setBackground (Bild); Was ist ** drawView ** in dieser Zeile? –

Antwort

2

Es sieht so aus, als ob Sie nur eine Ansicht (Ebene) verwenden, in der Sie zuerst ein Hintergrundbild einfügen und dann die Pfade zeichnen, die den Hintergrund ersetzen. Wenn dies der Fall ist, entfernen Sie beim Löschen die einzige Ansicht/Ebene, die die Pfade und den Hintergrund enthält. Wenn Sie zwei Ebenen verwenden (zwei Ansichten in einem Framelayout), eine auf der Rückseite, auf der Sie den Hintergrund laden möchten, und eine auf der Vorderseite, auf der Sie alle Pfade platzieren, werden nur die Pfade und der Hintergrund gelöscht durchkommen.

Es gibt verschiedene Möglichkeiten, das Layering durchzuführen. Als ein Beispiel, ersetzt diese FrameLayout die Ansicht, dass der Hintergrund und die gezogenen Pfade zur Zeit hält (siehe als XXXView im Code.)

<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> 
+0

Kannst du mir in einem Beispielcode zeigen, wie die Schichtung funktioniert? –

+0

Danke für das Beispiel, das funktioniert perfekt! gute Arbeit!!!! –