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:
-
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() -
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) -
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)lubinvalidate(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()lubpostInvalidate()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.