Почему requestLayout вызывается сразу после аннулирования

Я узнаю о пользовательских представлениях и хотел узнать о invalidate() а также requestLayout(),

Пожалуйста, обратитесь к этому ответу и его диаграмме:

/questions/35703792/ispolzovanie-forcelayout-requestlayout-i-invalidate/35703793#35703793

invalidate() сообщает Android, что состояние представления изменилось и его необходимо перерисовать.

requestLayout() означает, что размер представления, возможно, изменился и нуждается в повторном измерении, а затем перерисовывается.

invalidate() вызовет dispatchDraw(), draw(), а также onDraw() следовательно, это повторно представляет представление.

requestLayout() с другой стороны, делает практически все: от измерения до повторного рендеринга.

Почему так много примеров там (даже TextView исходный код) вызов invalidate() а потом requestLayout() прямо на следующей строке?

4 ответа

Решение

invalidate() используется специально для перерисовки содержимого вашего представления. Перерисовка не происходит синхронно. Вместо этого он помечает область вашего представления как недопустимую, поэтому он будет перерисован во время следующего цикла рендеринга.

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

Если вы не делаете что-либо на ваш взгляд, что бы изменить его размер, то вам не нужно звонить requestLayout(),

Если вы вернетесь и посмотрите на места в коде для TextView где requestLayout() вызывается, это будет на методах, где будут затронуты границы представления. Например, setPadding(), setTypeface(), setCompoundDrawables(), так далее.

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

Увидев следующую диаграмму, у меня сложилось впечатление, что requestLayout() в конечном итоге приведет к onDraw,

введите описание изображения здесь

Следовательно, не было бы необходимости называть их вместе, потому что это было бы излишним.

invalidate();
requestLayout();

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

Мой источник (благодаря этому комментарию) - Romain Guy (инженер по Android в Google):

Сам по себе requestLayout() не приводит к прохождению отрисовки, но некоторые представления могут реагировать на изменение макета, вызывая invalidate.

Поэтому, чтобы быть уверенным, что ретрансляция приведет к перерисовке, вам следует создать пару invalidate() с requestLayout(), (Однако обратное неверно. Если вам нужен только перерисовать, то нет необходимости звонить requestLayout(), Один invalidate() Сделаю.)

Соответствующий отрывок из книги " Эксперт Android", которая отвечает на вопрос:

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

Документы для Android: создание класса View

public boolean isShowText() {
   return mShowText;
}

public void setShowText(boolean showText) {
   mShowText = showText;
   invalidate();
   requestLayout();
}

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

Другие вопросы по тегам