Sobes.tech
Junior

Jak wywołać ponowne rysowanie niestandardowego widoku w Android?

sobes.tech AI

Odpowiedź od AI

Istnieje kilka sposobów wywołania odświeżenia (invalidate) niestandardowego widoku:

  1. invalidate():

    • Odświeża cały widok.
    • Planowane wywołanie onDraw().
    • Używane do prostego odświeżenia bez określenia konkretnego obszaru.
    // Wewnątrz Twojego widoku lub podczas interakcji z nim
    myCustomView.invalidate()
    
  2. invalidate(Rect dirty) lub invalidate(int left, int top, int right, int bottom):

    • Odświeża tylko wskazany obszar widoku.
    • Bardziej optymalne, jeśli zmiany dotyczą tylko części widoku.
    // Odśwież obszar o współrzędnych (10, 20) do (100, 150)
    myCustomView.invalidate(10, 20, 100, 150)
    
    // Lub za pomocą Rect
    val dirtyRect = Rect(10, 20, 100, 150)
    myCustomView.invalidate(dirtyRect)
    
  3. postInvalidate():

    • Bezpieczne do wywołania z dowolnego wątku, w tym z wątków w tle.
    • Umieszcza operację invalidate() w kolejce wiadomości do wykonania na wątku UI.
    // Wywołanie z wątku w tle
    Thread {
        // Wykonaj długie obliczenia
        // ...
        myCustomView.postInvalidate()
    }.start()
    

Porównanie invalidate() i postInvalidate():

Metoda Wątek wykonania Bezpieczeństwo z wątku w tle Przeznaczenie
invalidate() Wątek UI Nie Natychmiastowe odświeżenie (tak blisko wątku UI, jak to możliwe)
postInvalidate() Wątek UI Tak Odświeżenie odroczone przez kolejkę wiadomości

Związek z onDraw():

Wywołanie dowolnej z metod invalidate(...) planuje wykonanie metody onDraw() Twojego widoku. System Android łączy kilka żądań invalidacji w jedno, jeśli to możliwe, aby zoptymalizować wydajność. onDraw() jest wywoływane tylko wtedy, gdy system jest gotowy do ponownego rysowania.

Kiedy używać każdą metodę:

  • Używaj invalidate(), gdy jesteś w wątku UI (np. w obsłudze kliknięcia, po animacji) i zmiany dotyczą całego widoku lub nie zależy Ci na optymalizacji obszaru.
  • Używaj invalidate(Rect) lub invalidate(int, int, int, int) do optymalizacji, jeśli zmiany dotyczą tylko części widoku i jesteś w wątku UI.
  • Używaj postInvalidate(), gdy musisz wywołać invalidate z wątku w tle.
  • Nie wywołuj invalidate() lub postInvalidate() zbyt często bez potrzeby, ponieważ może to negatywnie wpłynąć na wydajność. Wywołuj je tylko po zmianach danych lub stanu widoku, które wymagają aktualizacji wizualnej.