Sobes.tech
Junior

Как да извикаме повторното рисуване на персонализирано View в Android?

sobes.tech AI

Отговор от 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. Android системата обединява няколко заявки за invalidate в една, ако е възможно, за оптимизация на производителността. onDraw() се извиква само когато системата е готова за преизчисляване.

Кога да използвате всеки метод:

  • Използвайте invalidate(), когато сте на UI потока (например, в обработчик на клик, след анимация) и промените засягат цялото View или не ви е важна оптимизацията по област.
  • Използвайте invalidate(Rect) или invalidate(int, int, int, int) за оптимизация, ако промените засягат само част от View и сте на UI потока.
  • Използвайте postInvalidate(), когато трябва да извикате invalidate от фоново нишка.
  • Не извиквайте invalidate() или postInvalidate() прекалено често без нужда, тъй като това може да повлияе негативно на производителността. Извиквайте ги само след промяна на данни или състояние на View, които изискват визуално обновяване.