it-swarm.com.ru

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

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

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

155
fiddler

Чтобы лучше понять ответы, предоставленные Francois BOURLIEUX и Dalvik Я предлагаю вам взглянуть на эту потрясающую диаграмму жизненного цикла представления с помощью Arpit Mathurenter image description here

314
Bartek Lipinski

invalidate()

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

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

requestLayout()

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

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

invalidate();
requestLayout();

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

forceLayout()

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

Прочитайте это вопросы и ответы для более подробного описания forceLayout().

Дальнейшее обучение

101
Suragch

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

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

25
François BOURLIEUX

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

3
Nativ

Этот ответ неверно относительно forceLayout().

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

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

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

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

3
fluidsonic