Использование forceLayout (), requestLayout () и invalidate ()

Я немного смущен о ролях методов forceLayout() , requestLayout() и invalidate() класса View .

Когда они будут называться?

Чтобы лучше понять ответы, предоставленные François BOURLIEUX и Dalvik, я предлагаю вам взглянуть на эту удивительную диаграмму жизненного цикла View by Arpit Mathur : Введите описание изображения здесь

invalidate()

Вызов invalidate() выполняется, если вы хотите запланировать перерисовку представления. Это приведет к onDraw что onDraw будет вызван в конечном итоге (вскоре, но не сразу). Примером того, когда пользовательское представление вызывало бы это, является изменение свойства текста или фона.

Представление будет перерисовано, но размер не изменится.

requestLayout()

Если что-то изменится в вашем представлении, что повлияет на размер, вы должны вызвать requestLayout() . Это вызовет onMeasure и onLayout не только для этого представления, но и для линии для родительских представлений.

При requestLayout() не гарантируется результат onDraw (вопреки тому, что подразумевает диаграмма в принятом ответе), поэтому его обычно объединяют с invalidate() .

 invalidate(); requestLayout(); 

Примером этого может служить изменение пользовательского ярлыка. Этикетка изменит размер и, следовательно, необходимо будет переоценить и перерисовать.

forceLayout()

Вызов forceLayout() если вы хотите только передать содержимое своего собственного представления, но не нужно инициировать повторное измерение всего дерева представлений (все родительские представления). Если у вас была пользовательская ViewGroup которая не меняла свой собственный размер, но для переоценки и ретрансляции своих детей это было бы подходящей ситуацией для вызова forceLayout() .

В принципе, вызов requestLayout() приводит к вызову parent.requestLayout() , но вызов forceLayout() не выполняется.

Дальнейшее изучение

  • Создание класса просмотра: добавление свойств и событий (полезные документы)
  • Просмотр документации
  • View исходный код

Здесь вы можете найти ответ: http://developer.android.com/guide/topics/ui/how-android-draws.html

Для меня вызов invalidate() только обновляет представление, а вызов requestLayout() обновляет представление и вычисляет размер представления на экране.

Вы используете invalidate () в представлении, которое вы хотите перерисовать, оно сделает его onDraw (Canvas c) для вызова, а requestLayout () сделает повторную визуализацию всего кадра (фаза измерения и фаза позиционирования). Вы должны использовать его, если вы изменяете размер дочернего представления во время выполнения, но только в отдельных случаях, таких как ограничения из родительского представления (под этим я подразумеваю, что высота или ширина родителя – WRAP_CONTENT и поэтому соответствуют мерам детей, прежде чем они смогут их снова обернуть)

Этот ответ forceLayout() отношении forceLayout() .

Как вы можете видеть в коде forceLayout() он просто отмечает представление как «нуждается в ретрансляторе», но он не планирует и не запускает этот ретранслятор. Ретрансляция не произойдет до тех пор, пока в какой-то момент в будущем родительский вид представления не будет изложен по какой-либо другой причине.

Существует также гораздо большая проблема при использовании forceLayout() и requestLayout() :

Предположим, вы вызвали forceLayout() на представлении. Теперь при вызове функции requestLayout() на requestLayout() этого представления Android будет рекурсивно вызывать requestLayout() для предков этого потомка. Проблема в том, что она остановит рекурсию в представлении, на которое вы forceLayout() . Таким образом, requestLayout() никогда не достигнет корня представления и, следовательно, никогда не будет планировать прохождение макета. Весь requestLayout() иерархии представлений ожидает макета, и вызов requestLayout() в любом представлении этого поддерева не приведет к созданию макета. Только вызов requestLayout() в любом представлении вне этого поддерева будет нарушать заклинание.

Я бы рассмотрел реализацию forceLayout() (и как он влияет на requestLayout() чтобы быть сломанным, и вы никогда не должны использовать эту функцию в своем коде.

Intereting Posts
Пользовательский вид сетки с диапазоном строк и диапазоном столбцов Что означает оранжевый треугольник в целевом столбце окна Android Device Chooser? Android Vibrate on toast (Гомер: Mmmm вибрирует на тосте) Запретить перехватывать ссылки Listview при использовании его Child MapView Запуск приложения замедлился: не удалось открыть '/system/framework/dpmapi.jar' Вложенная реализация рекурсивного просмотра, например приложение Google Play Store Как использовать RecyclerView, пытаясь следовать за предложением разработчика.android.com, но получить ошибку Элементы Listview удаляют растровые изображения из памяти, когда пользователь прокручивает Заполните оставшееся пространство с фиксированным соотношением сторон изображения Единичный тест на функцию расширения Kotlin на Android SDK Classes Является ли R.layout.listview таким же, как R.id.listview Открытое приложение для получения уведомлений о пожарной базе (FCM) Webview избегает предупреждения безопасности из игры Google при реализации onReceivedSslError Android – OutOfMemory при декодировании Растровое изображение из ресурсов на Android 5.0 Кордова 3.5.0 Ошибка установки – установите Android-цель 19