2010-03-11 4 views
16

Ich versuche, eine Animation zu zeichnen. Dazu habe ich View erweitert und die onDraw() -Methode überschrieben. Was ich erwarten würde, ist, dass jedes Mal, wenn onDraw() aufgerufen wird, der Canvas in dem Zustand ist, in dem ich ihn gelassen habe, und ich könnte ihn löschen oder einfach nur Teile davon zeichnen (So funktionierte es, wenn ich ein SurfaceView verwendete)) aber jedes Mal kommt die Leinwand schon wieder klar. Gibt es einen Weg, den ich nicht klären kann? Oder speichern Sie vielleicht den vorherigen Zustand in eine Bitmap, also kann ich einfach diese Bitmap zeichnen und dann darüber zeichnen?Android View.onDraw() hat immer eine saubere Canvas

Antwort

28

Ich bin mir nicht sicher, ob es einen Weg gibt oder nicht. Aber für meine benutzerdefinierten Ansichten zeichne ich entweder alles neu, wenn onDraw() aufgerufen wird, oder zeichne auf eine Bitmap und zeichne dann die Bitmap auf die Leinwand (wie du es in deiner Frage vorgeschlagen hast).

Hier ist, wie ich es tun

class A extends View { 

    private Canvas canvas; 
    private Bitmap bitmap; 

    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     if (bitmap != null) { 
      bitmap .recycle(); 
     } 
     canvas= new Canvas(); 
     bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     canvas.setBitmap(bitmap); 
    } 
    public void destroy() { 
     if (bitmap != null) { 
      bitmap.recycle(); 
     } 
    } 
    public void onDraw(Canvas c) { 
     //draw onto the canvas if needed (maybe only the parts of animation that changed) 
     canvas.drawRect(0,0,10,10,paint); 

     //draw the bitmap to the real canvas c 
     c.drawBitmap(bitmap, 
      new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()), 
      new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()), null); 
    } 
} 
+0

Ich habe das vor kurzem herausgefunden! Danke für die Eingabe! – CaseyB

+0

Zeichnung zu Puffer funktioniert gut, aber diese riesige DrawBitmap() -Methode isst viele FPS :( –

+0

Es ist ein Flaschenhals für mich jetzt - FullScreen Bitmap in OnDraw jedes Mal zu zeichnen, um früheren Zustand wiederherstellen wirkt sich kaum auf FPS für hochauflösende Geräte (wie Kindle 8.9 3rd Gen mit 2560x1600) Gibt es wirklich keine Möglichkeit, Canvas zu zwingen, den vorherigen Zustand zu behalten? Eine Vertiefung in OpenGL kann wahrscheinlich das Leistungsproblem lösen, aber es ist nicht die Art zu der Zeit. –

1

sollten Sie einen Blick here haben, um den Unterschied zwischen Grundansicht und Oberflächenansicht zu sehen. Ein SurfaceView verfügt über eine dedizierte Ebene zum Zeichnen, von der ich denke, dass Sie das, was Sie zuvor gezeichnet haben, verfolgen. Nun, wenn Sie es wirklich in einer einfachen Ansicht machen möchten, könnten Sie versuchen, jedes Element, das Sie zeichnen, in ein Array zu setzen, wie das Beispiel itemized overlay for the mapview. Es sollte ziemlich genau so funktionieren

+0

Ich sah diese Seite. In der Tat führte mich diese Seite anfangs dazu, ein SurfaceView zu verwenden, aber dann stellte ich fest, dass das SurfaceView keinen transparenten Hintergrund haben konnte. und ich brauche dieses Widget, um auf anderen Ansichten sitzen zu können. – CaseyB

+0

dann versuchen Sie das Array von Zeichen? – Sephy

+0

Im modernen Android können Sie eine Texturansicht verwenden, wenn Sie die OpenGL-Route gehen möchten. – Adam

0

Ihre Erwartungen jib nicht w/Realität :) Die Leinwand wird den Weg nicht Sie es verlassen haben, aber es leer statt. Sie könnten eine ArrayListe von Objekten erstellen, die gezeichnet werden sollen (canvas.drawCircle(), canvas.drawBitmap() usw.), und dann iterieren Sie die ArrayList in OnDraw(). Ich bin neu in der Grafikprogrammierung, aber ich habe das in kleinem Umfang verwendet. Vielleicht gibt es einen viel besseren Weg.

+0

Es ist, wenn Sie die Leinwand erstellen. Auf diese Weise haben Sie die totale Kontrolle darüber, was gezeichnet wird .. – CaseyB

+0

Anstelle eines Arraylists: Sie können die Picture-Klasse zum Aufzeichnen von Zeichnungsaufrufen verwenden. –

Verwandte Themen