Junior
Wie löst man das Nezeichnen einer benutzerdefinierten View in Android aus?
sobes.tech KI
Antwort von AI
Es gibt mehrere Möglichkeiten, eine benutzerdefinierte Ansicht zu invalidieren (invalidate):
-
invalidate():
- Zeichnet die gesamte Ansicht neu.
- Plant den Aufruf von
onDraw(). - Wird für eine einfache Nezeichnung ohne Angabe eines bestimmten Bereichs verwendet.
// Innerhalb Ihrer Ansicht oder bei Interaktion mit ihr myCustomView.invalidate() -
invalidate(Rect dirty) oder invalidate(int left, int top, int right, int bottom):
- Zeichnet nur den angegebenen Bereich der Ansicht neu.
- Ist effizienter, wenn Änderungen nur einen Teil der Ansicht betreffen.
// Den Bereich mit Koordinaten (10, 20) bis (100, 150) neu zeichnen myCustomView.invalidate(10, 20, 100, 150) // Oder mit Rect val dirtyRect = Rect(10, 20, 100, 150) myCustomView.invalidate(dirtyRect) -
postInvalidate():
- Ist sicher, von jedem Thread aus aufgerufen zu werden, auch von Hintergrund-Threads.
- Legt die Operation
invalidate()in die Nachrichtenwarteschlange, um sie im UI-Thread auszuführen.
// Aus einem Hintergrund-Thread Thread { // Lange Berechnungen durchführen // ... myCustomView.postInvalidate() }.start()
Vergleich zwischen invalidate() und postInvalidate() :
| Methode | Ausführungsthread | Sicherheit aus Hintergrund-Thread | Zweck |
|---|---|---|---|
invalidate() |
UI-Thread | Nein | Sofortiges Nezeichnen (so weit wie möglich im UI-Thread) |
postInvalidate() |
UI-Thread | Ja | Verzögertes Nezeichnen durch Nachrichtenwarteschlange |
Beziehung zu onDraw() :
Der Aufruf einer beliebigen Methode invalidate(...) plant die Ausführung von onDraw() Ihrer View. Das Android-System fasst mehrere invalidate-Anfragen zusammen, wenn möglich, um die Leistung zu optimieren. onDraw() wird nur aufgerufen, wenn das System zum Nezeichnen bereit ist.
Wann jede Methode verwenden:
- Verwenden Sie
invalidate(), wenn Sie sich im UI-Thread befinden (z.B. in einem Klick-Handler, nach einer Animation) und Änderungen die gesamte View betreffen oder Sie keine Optimierung nach Bereich wünschen. - Verwenden Sie
invalidate(Rect)oderinvalidate(int, int, int, int), um die Optimierung zu nutzen, wenn Änderungen nur einen Teil der View betreffen und Sie im UI-Thread sind. - Verwenden Sie
postInvalidate(), wenn Sie invalidate aus einem Hintergrund-Thread aufrufen müssen. - Rufen Sie
invalidate()oderpostInvalidate()nicht zu häufig ohne Grund auf, da dies die Leistung beeinträchtigen kann. Rufen Sie sie nur nach Änderungen an Daten oder Zustand der View auf, die eine visuelle Aktualisierung erfordern.