2010-03-11 14 views
16

Sto provando a disegnare un'animazione. Per fare ciò ho esteso View e sovrascritto il metodo onDraw(). Quello che mi aspetterei è che ogni volta che onDraw() viene chiamato, la tela si troverebbe nello stato in cui l'ho lasciata e potrei scegliere di cancellarla o disegnarne solo alcune parti (questo è il modo in cui ha funzionato quando ho usato SurfaceView) ma ogni volta che la tela torna già cancellata. C'è un modo in cui non posso averlo eliminato? O magari salvare lo stato precedente in una bitmap, quindi posso semplicemente disegnare quel bitmap e poi disegnarlo sopra?Android View.onDraw() ha sempre una tela pulita

risposta

28

Non sono sicuro che ci sia un modo o meno. Ma per le mie viste personalizzate posso ridisegnare ogni volta ogni volta che si chiamaDraw(), o disegnare in una bitmap e quindi disegnare la bitmap sul canvas (come suggerito nella domanda).

Ecco come lo faccio

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

L'ho capito solo un po 'di tempo fa! Grazie per l'input! – CaseyB

+0

Il disegno sul buffer funziona bene, ma questo enorme metodo drawBitmap() mangia molto FPS :( –

+0

È un collo di bottiglia per me in questo momento: disegnare bitmap a schermo intero in onDraw ogni volta per ripristinare lo stato precedente impatta FPS per i dispositivi ad alta risoluzione (come Kindle 8.9 3rd gen con 2560x1600). Non c'è davvero alcun modo per forzare il persistere del canvas è stato precedente? Approfondire in OpenGL può probabilmente risolvere problemi di prestazioni, tuttavia non è il modo per il momento. –

1

si dovrebbe dare un'occhiata here per vedere la differenza tra vista di base e surfaceView. Un surfaceView ha uno strato dedicato per il disegno, che suppongo tenga traccia di ciò che hai disegnato in precedenza. Ora se vuoi davvero farlo su una vista di base, puoi provare a mettere ogni elemento che disegni in una matrice, come nell'esempio di itemized overlay for the mapview. Dovrebbe funzionare più o meno allo stesso modo

+0

Ho visto quella pagina. In effetti quella pagina mi ha portato a utilizzare inizialmente SurfaceView, ma poi ho scoperto che SurfaceView non può avere uno sfondo trasparente. e ho bisogno di questo widget per essere in grado di sedere su altre viste. – CaseyB

+0

quindi prova la matrice di drawable? – Sephy

+0

Nel moderno Android è possibile utilizzare una vista texture se si desidera utilizzare la rotta OpenGL. – Adam

0

Le vostre aspettative non fiocco w/realtà :) La tela non sarà il modo in cui hai lasciato, ma è vuota invece. È possibile creare una lista array di oggetti da disegnare (canvas.drawCircle(), canvas.drawBitmap(), ecc.), Quindi eseguire iterazione tramite ArrayList in OnDraw(). Sono nuovo alla programmazione grafica ma l'ho usato su piccola scala. Forse c'è un modo molto migliore.

+0

È se si crea il canvas. In questo modo hai il controllo totale su ciò che viene disegnato. – CaseyB

+0

Invece di un Arraylist: puoi usare la classe Picture per registrare le chiamate di disegno. –