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

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

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

Ответ 1

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

Ответ 2

invalidate()

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

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

requestLayout()

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

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

invalidate();
requestLayout();

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

forceLayout()

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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

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

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