Назад к вопросам
Junior
78
questionbank
Как вызвать перерисовку кастомного View в Android?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Существует несколько способов вызвать перерисовку (invalidate) кастомного View:
-
invalidate():
- Перерисовывает весь View.
- Планирует вызов
onDraw(). - Используется для простой перерисовки без указания конкретной области.
// Внутри вашего View или при взаимодействии с ним myCustomView.invalidate() -
invalidate(Rect dirty) или invalidate(int left, int top, int right, int bottom):
- Перерисовывает только указанную область View.
- Более оптимально, если изменения затрагивают лишь часть View.
// Перерисовать область с координатами (10, 20) по (100, 150) myCustomView.invalidate(10, 20, 100, 150) // Или с помощью Rect val dirtyRect = Rect(10, 20, 100, 150) myCustomView.invalidate(dirtyRect) -
postInvalidate():
- Безопасен для вызова из любого потока, в том числе из фоновых.
- Помещает операцию
invalidate()в очередь сообщений для выполнения на UI-потоке.
// Вызов из фонового потока Thread { // Выполняем долгие вычисления // ... myCustomView.postInvalidate() }.start()
Сравнение invalidate() и postInvalidate():
| Метод | Поток выполнения | Безопасность из фонового потока | Назначение |
|---|---|---|---|
invalidate() |
UI-поток | Нет | Немедленная перерисовка (насколько это возможно в UI-потоке) |
postInvalidate() |
UI-поток | Да | Отложенная перерисовка путем постановки в очередь сообщений |
Связь с onDraw():
Вызов любого из методов invalidate(...) планирует выполнение метода onDraw() вашего View. Cистема Android объединяет несколько запросов на invalidate в один, если это возможно, для оптимизации производительности. onDraw() вызывается только тогда, когда система готова к перерисовке.
Когда использовать каждый метод:
- Используйте
invalidate(), когда вы находитесь в UI-потоке (например, в обработчике клика, после анимации) и изменения затрагивают весь View или вам не важна оптимизация по области. - Используйте
invalidate(Rect)илиinvalidate(int, int, int, int)для оптимизации, если изменения затрагивают только часть View, и вы находитесь в UI-потоке. - Используйте
postInvalidate(), когда вам нужно вызвать invalidate из фонового потока. - Не вызывайте
invalidate()илиpostInvalidate()слишком часто без необходимости, так как это может негативно сказаться на производительности. Вызывайте их только после изменения данных или состояния View, которые требуют визуального обновления.