перестраивание дерева виджетов

Хочу задать во многом уточняющий вопрос для себя о дереве. Правильно ли я понимаю что при создании StatefulWidget, при обновлении именно его состояния, все те StatefulWidget'ы которые в нем будут перестраиваться, в то время как StatelessWidget нет. То есть те "ветки-виджеты" StatefulWidget будут перерисованы. Правильное ли это утверждение? Везде пишут подобные слова.... Также меня инересует термин перестройки или rebuild. Это говорит о том что виджеты по факту будут пересозданы? Но в таком случае мое утверждение не верно, ибо в таком случае вероятно должны пересоздаться и StatelessWidget виджеты, если только они не кешируются в некотором роде. Поясните пожалуйста мне момент перестройки дерева виджетов.

Заранее благодарен


Ответы (1 шт):

Автор решения: MiT

Чтобы понять как происходит обновление виджета, надо узнать из чего состоит его дерево. Когда вы создаете новый виджет вы создаете сразу три связанных объекта дерева для него:

  1. Widget — Describes the configuration for an [Element] (Widget это описание некоторого Element).
  2. Element — An instantiation of a [Widget] at a particular location in the tree (Element это некоторое представление виджета в определенном месте дерева).
  3. RenderObject — это объект дерева визуализации, то что мы видим в итоге.

На примере данного небольшого кода рассмотрим дерево:

Container(
  color: Colors.blue,
  child: Row(
    children: [
      Image.network('https://www.example.com/1.png'),
      Text('A'),
    ],
  ),
);

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

Как вы можете заметить Widget и Element идут один к одному. Но вот RenderObject есть не у всех виджетов, так как некоторые виджеты являются делигаторами (например Container) для других виджетов. Также надо понимать что RenderObject отобразиться/обновится лишь когда Element разрешит ему.

Как происходит обновление виджета:

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

Когда ваш виджет помечается dirty (при setState и др.) происходит сравнение нового и старого виджета по runtimeType и key. Если они не совпадают то все дерево ниже просто отбрасывается и создается новое, если они совпадают, то просто идет замена Widget объекта, без изменения Element.

Важно прочитать, чтобы разобраться подробнее:


Небольшие замечания:

  1. Различие между StatefulWidget и StatelessWidget, в том что у Stateful есть State и LifeCycle в остальном по дереву они идентичны.
  2. У каждого Element может быть по разному приходить вызов RenderObject, но в большинстве случаем он приходит при создании.
  3. Key могут очень сильно влиять на перебилд виджетов.
  4. В дереве виджетов есть множество оптимизаций, чтобы сделать билд быстрым (а в некоторых случаях вообще его не делать если не будет смысла)
→ Ссылка