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



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



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

666   5  

5 ответов:

чтобы лучше понять ответы Франсуа Бурле и Далвик Я предлагаю вам взглянуть на этот удивительный вид схема жизненного цикла Матур Арпит: enter image description here

invalidate()

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

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

requestLayout()

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

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

invalidate();
requestLayout();

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

forceLayout()

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

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

дальнейшего изучения

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

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

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

ответ не правильно о forceLayout().

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

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

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

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

Comments

    Ничего не найдено.