2010-06-01 13 views
14

Ich habe eine benutzerdefinierte Ansicht, die meinen gesamten Bildschirm füllt. (Eine Klaviertastatur) Wenn ein Benutzer die Taste berührt, wird invalidate() aufgerufen und die gesamte Tastatur wird neu gezeichnet, um den neuen Zustand mit einem berührten Schlüssel anzuzeigen.Android: Wie wird eine benutzerdefinierte Ansicht teilweise neu gezeichnet?

Derzeit ist die Ansicht sehr einfach, aber ich plane, ein bisschen mehr nette Grafiken hinzuzufügen. Da die gesamte Tastatur dynamisch gerendert wird, würde dies das Neuzeichnen der gesamten Tastatur teurer machen.

Also dachte ich, lass uns in teilweise Neuzeichnen schauen. Jetzt rufe ich invalidate(Rect dirty) mit der korrekten schmutzigen Region an. Ich setze meine onDraw(Canvas canvas) Methode, um nur die Schlüssel in der schmutzigen Region zu zeichnen, wenn ich tatsächlich eine teilweise Neuzeichnung wünsche. Dies führt dazu, dass diese Tasten gezeichnet werden, aber der Rest der Tastatur ist komplett schwarz/nicht gezeichnet.

Bin ich falsch darin zu erwarten, dass das Aufrufen von invalidate(Rect dirty) würde die aktuelle canvas "zwischenspeichern" und nur "erlaubt" in der schmutzigen Region zeichnen?

Gibt es irgendeine Möglichkeit, dass ich erreichen kann, was ich will? (Ein Weg, um „Cache“ die Leinwand und nur den schmutzigen Bereich neu zu zeichnen“

Antwort

18

Aktuelle schöne Abhilfe ist, die volle Leinwand in eine Bitmap manuell cachen:

private void onDraw(Canvas canvas) 
{ 
    if (!initialDrawingIsPerformed) 
    { 
      this.cachedBitmap = Bitmap.createBitmap(getWidth(), getHeight(), 
      Config.ARGB_8888); //Change to lower bitmap config if possible. 
      Canvas cacheCanvas = new Canvas(this.cachedBitmap); 
      doInitialDrawing(cacheCanvas); 
      canvas.drawBitmap(this.cachedBitmap, 0, 0, new Paint()); 
      initialDrawingIsPerformed = true; 
    } 
    else 
    { 
      canvas.drawBitmap(this.cachedBitmap, 0, 0, new Paint()); 
      doPartialRedraws(canvas); 
    } 
} 

Ofcourse, müssen Sie die Informationen speichern, über das, was neu gezeichnet werden sollte und vorzugsweise nicht ein neues Paint jedes Mal, aber das sind Details

Beachten Sie auch: Bitmaps sind ziemlich schwer auf die Speichernutzung Ihrer App. Ich hatte Abstürze, wenn ich eine View zwischengespeichert hatte ein Scroller und das war wie 5 mal die Höhe des Geräts, da es> 10MB Speicher verwendet!

+1

Hmm, ich mag diese Lösung nicht, weil der Grund, warum seine Schlüssel teilweise gezeichnet sind, ist, weil er sowieso zuerst eine volle Auslosung seiner Kanvas haben sollte. Die Frage ist also, warum seine Leinwand überhaupt nicht richtig gezeichnet hat. –

+1

Ich muss beachten, dass ich jetzt verstehe, dass wenn Sie 'invalidate' mit einem dirty' rect' aufrufen, Sie einfach Ihren normalen Zeichnungscode verwenden können, und es sollte nur die Zeichenoperationen ausführen, die sich in der schmutzigen 'rect' befinden. 'Canvas' verwirft die Operationen, die außerhalb des' rect' liegen. Dennoch bedeutet dies, dass viel von Ihrem eigenen Code immer noch gerendert wird und in meinen Tests mit HW-Beschleunigung war es langsamer als nur die Ansicht vollständig zu rendern. – Peterdk

+1

Beachten Sie, dass zum Zeichnen von Bitmaps auf Canvas der Farbparameter null sein kann, z. 'canvas.drawBitmap (Bitmap, 0, 0, null)'. – greg7gkb

5

Um Peterdks Antwort zu ergänzen, könnten Sie Ihre Operationen in einem Bild anstelle einer Bitmap speichern.

  • Ein Bitmap alle Pixel speichern, wie er sagte, es eine Menge Speicher nehmen könnte.
  • Ein Bild wird die Anrufe, wie drawRect, drawLine speichern usw.

Es hängt von dem, was in Ihrer Anwendung wirklich schwer ist: viele Ziehoperationen, einige ziehen Operationen aber kontrolliert durch schwere Berechnungen , eine Menge leerer/unbenutzter Platz (lieber Bild) etc ...

+0

Schön, schau dir das an! – Peterdk

+0

Entschuldigung. Wird der 'Bild'-Datensatz' drawBitmap (Bitmap) 'aufrufen? Wahrscheinlich nein, oder? – Yeung

+0

Beachten Sie, dass die Bildwiedergabe nur auf Software-Leinwänden unterstützt wird. Daher können Sie für Ansichten, die dies verwenden, keine Hardware-Ebenen verwenden. – greg7gkb

Verwandte Themen