Sobes.tech
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):

  1. 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()
    
  2. 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)
    
  3. 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) oder invalidate(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() oder postInvalidate() 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.