Назад к вопросам
Junior
78
questionbank

Как вызвать перерисовку кастомного View в Android?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Существует несколько способов вызвать перерисовку (invalidate) кастомного View:

  1. invalidate():

    • Перерисовывает весь View.
    • Планирует вызов onDraw().
    • Используется для простой перерисовки без указания конкретной области.
    // Внутри вашего View или при взаимодействии с ним
    myCustomView.invalidate()
    
  2. 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)
    
  3. 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, которые требуют визуального обновления.