Я немного запутался в ролях методов forceLayout(), requestLayout() и invalidate() класса View.
Когда они будут называться?
Я немного запутался в ролях методов forceLayout(), requestLayout() и invalidate() класса View.
Когда они будут называться?
Чтобы лучше понять ответы, предоставленные François BOURLIEUX и Dalvik Я предлагаю вам взглянуть на этот удивительный просмотреть диаграмму жизненного цикла Arpit Mathur:

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()), и вы никогда не должны использовать эту функцию в своем коде.