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

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

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

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

invalidate()

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

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

requestLayout()

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

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

 invalidate(); requestLayout(); 

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

forceLayout()

Когда есть requestLayout() который вызывается в родительской группе просмотра, нет необходимости пересматривать и ретранслировать его дочерние представления. Однако, если ребенок должен быть включен в remeasure и relayout, вы можете вызвать forceLayout() для ребенка. forceLayout() работает только с дочерним forceLayout() если он встречается в соединении с requestLayout() для его прямого родителя. Вызов forceLayout() сам по себе не будет иметь эффекта, поскольку он не вызывает requestLayout() вверх по дереву представления.

Прочтите это Q & A для более подробного описания forceLayout() .

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

  • Создание classа просмотра: добавление свойств и событий (полезные документы)
  • Просмотр документации
  • 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() на любом представлении вне этого поддерева будет нарушать заклинание.

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

  • Какова роль content_main.xml в android studio 1.4?
  • как создать собственный счетчик, как рамка вокруг спиннера с треугольником вниз с правой стороны?
  • Как создать горизонтальный ListView с помощью RecyclerView?
  • Изменение цвета фона выбранного элемента в ListView
  • Почему LayoutInflater игнорирует параметры layout_width и layout_height, которые я указал?
  • Как раздуть один вид с помощью макета
  • Динамическое добавление содержимого в линейную компоновку?
  • Нарисовать круг на ощупь
  • Добавить новый элемент в значок на кнопке - Android
  • Ошибка раздувания fragmentа classа
  • Просмотр с горизонтальным и вертикальным панорамированием / drag and dropм и усилением
  • Давайте будем гением компьютера.