1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/CarGuo-GSYFlutterBook

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Flutter-6.md 8.4 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 10.03.2025 00:06 5767d61

Как шестая статья в серии, эта статья рассматривает некоторые интересные принципы работы виджетов на основе предыдущих исследований.

Ссылка на статью:

Полный гайд по Flutter: серия статей

Попутные заметки о мире Flutter: серия статей

Сначала нам следует понять, что такое виджет? Здесь есть «общий знаменатель»: виджеты сами по себе не являются объектами отрисовки. Да, действительно, в Flutter процесс отрисовки проходит через этапы от Widget до Element, а затем до RenderObject.

Мы знаем, что виджеты неизменяемы, но как они строят интерфейсы при этом? Мы уже выяснили, что Widget должен быть преобразован в Element для отображения, и из следующего примечания можно заключить, что виджет представляет собой конфигурационное описание для элемента, которое указывает элементу, как его отрисовать.

Какова же взаимосвязь между виджетом и элементом? Из вышеупомянутого примечания также следует, что виджет и элемент имеют отношение один ко многим. В действительности дерево отрисовки состоит из узлов, представляющих экземпляры элементов, а конфигурационные файлы виджетов могут быть переиспользованы в различных частях дерева, создавая множество объектов элемента.А что такое RenderObject? Как он связан с двумя другими компонентами? Из комментариев в исходном коде можно сделать вывод, что RenderObject является фактическим объектом отрисовки, а из исходного кода элемента видно, что элемент хранит RenderObject и Widget.

Объединив это с последующей диаграммой, можно сделать вывод, что три компонента имеют следующие отношения: конфигурационный файл Widget создаёт Element, который затем создаёт RenderObject, связывая его с внутренним объектом renderObject элемента, после чего Flutter использует данные RenderObject для размещения и отрисовки. Теоретически можно сказать, что RenderObject — это конечные данные для отрисовки Flutter, содержащие информацию о размерах и положении, которую Flutter использует для создания изображения.

Рассматривая RenderObject, нельзя не упомянуть RenderBox: «Отрисовочный объект в двумерной декартовой системе координат», из комментариев в исходном коде можно сделать вывод, что он реализует «декартовую систему координат» на основе базовых возможностей размещения и отрисовки, предоставленных RenderObject: система координат с вершиной и левой стороной в качестве базовых точек, использующая две оси — ширину и высоту — для размещения и вложения. RenderBox избавляет от необходимости непосредственно использовать сложные сценарии с RenderObject, где размещение и вычисление размера RenderBox выполняются в методах performLayout() и performResize(). Часто мы выбираем наследование RenderBox для реализации пользовательских компонентов.Учитывая вышеописанное, можно сделать вывод:

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

Поэтому для каждого изменения требуется проверка того, следует ли создать новый element и renderObject, или они могут быть переиспользованы. Например, если тип времени выполнения (runtimeType) и ключ (key) нового виджета (newWidget) совпадают с существующим виджетом (oldWidget), то используется новый виджет для обновления уже существующего объекта element. В противном случае создаётся новый объект element.

Из этого следует, что при пересоздании виджета деревья element и renderObject полностью не пересоздаются.

К слову, как мы можем получить размеры и положение размещения?

Для этого нам потребуется ранее упомянутый globalKey. Через этот ключ мы получаем контекст (buildContext) контролируемого элемента, а поскольку element хранит renderObject, то фактически мы получаем доступ к renderBox. Таким образом, через renderBox мы можем получить размеры и положение.```dart showSizes() { RenderBox renderBoxRed = fileListKey.currentContext.findRenderObject(); print(renderBoxRed.size); }

showPositions() { RenderBox renderBoxRed = fileListKey.currentContext.findRenderObject(); print(renderBoxRed.localToGlobal(Offset.zero)); }


---

> Так заканчивается шестая статья! (///▽///)

### Рекомендации по ресурсам

* GitHub: [https://github.com/CarGuo/](https://github.com/CarGuo/)
* **Открытый проект на Flutter: https://github.com/CarGuo/GSYGithubAppFlutter**
* **Множество примеров открытых проектов на Flutter: https://github.com/CarGuo/GSYFlutterDemo**
* **Открытая электронная книга по实战 Flutter: https://github.com/Yöntem CarGuo/GSYFlutterBook**

##### Рекомендация полного открытого проекта* [GSYGithubAppWeex](https://github.com/CarGuo/GSYGithubAppWeex)
* [GSYGithubApp React Native](https://github.com/CarGuo/GSYGithubApp)

![Сможем ли мы ещё встретиться?](http://img.cdn.guoshuyu.cn/20190604_Flutter-6/image4)

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/CarGuo-GSYFlutterBook.git
git@api.gitlife.ru:oschina-mirror/CarGuo-GSYFlutterBook.git
oschina-mirror
CarGuo-GSYFlutterBook
CarGuo-GSYFlutterBook
master