Pull to refresh
6
0
Адещенко Кирилл @kaparray

Engineer

Send message

Добрый день! Спасибо за комментарий. Отвечаю на ваши пункты:
1) спасибо
2) Думаю это вопрос "вкусовщины". Я считаю что интерфейс должен быть явно выделен. То есть название должно быть i_name_of_class.dart и имя класса INameOfClass. Это позволяет более явно отделить интерфейсы от реализации.
3) Моё мнение "всегда нужно исходить из бизнес потребностей".
4) Согласен. Вы уже мигрировали свой проект на dart 3? Расскажите опыт.

Как только закрывается экран пользователем или программно в бизнес логике, так сразу он буде удалён из истории. Пользователь может нажать физическую кнопку назад на своём устройстве, либо использовать программную в приложении для удаления.

Утечек памяти нет. По поводу переполнения могу сказать одно, сделал эксперимент с открытием 100 экранов в дереве и всё работало прекрасно!

Спасибо за фидбэк, уже есть в задумке написать туториал по сложной навигации. Он на самом деле вписывается в концепцию которую я описал в разделе “Best practice ”, так как я лично реализовал в этой парадигме навигацию с табами, фрагментами и тд

Согласен, но именно вызов метода pushNamed декларативен, так как знание о переходе скрыто от потребителя. То есть знание каким образом, как и куда реализовано в другом месте.
По поводу Navigator 2.0 я общался с @chunhtai пару месяцев назад и предлагал свою помощь. Точные сроки выхода нового принципа навигации никто не может назвать, но вдохновлялись Angular.
Я не буду с вами спорить. Советую более детально изучить Фреймворк. Видно что вы верхнеуровневого глянули на исходники и не видите всей картины.

Просто просьба не вводить людей в заблуждение:
1) У Flutter нет 3х параллельных деревьев! Это просто вложенные друг в друга абстракции. Созданы для разделения обязанностей между собой.
2) Где что храниться?
— Кол флу такой что создаётся StatefulWidget у него BuildOwner вызывает метод createElement и передаёт туда ссылку на виджет с помощью this.
Дальше в кострукторе StatefulElement вызывает метод createState у виджета.
Дальше в State прикидывает себя и виджет при помощи всё того же this ``` _state._element = this;``` и ``` _state._widget = widget;```.

Таким образом:
StatefulElement знает о widget и state и о своём родителе.
State знает о widget и element.
StatefuWidget — хранит ключ (Key).

3) Доступа к RenderObjectWidgets RenderObjectElement у меня нет.
То что вы привели — это просто абстракции, я говорил про конкретный пример.
Например _CupertinoDialogRenderWidget()
Я реализовывал полностью на канве свой StatefulWidget и прекрасно знаю как это всё устроено.

4) ```Глупо их просто разделять, так как вообще Element это одно из филдов в abstract class Widget.```
Тут согласен, имел ввиду конечно же State.

4) и опять к 3м параллельным деревьям
То что вы привели пример c абстрактными классами, это забавно. Изучите более детально.

Если у вас есть желание то можете со мной связаться в телеграм(kaparray) и я более детально вам скажу куда копать.

Хорошего дня)


Это больше похоже на элемент + виджет.

Ответ:
виджет — описание элемента. Смотрим исходники и видим:
«Widget — Describes the configuration for an [Element].»
Виджеты были сделаны только для того чтобы абстрагировать программистов от жизненного цикла и канаваса. Глупо их просто разделять, так как вообще Element это одно из филдов в abstract class Widget.



Но даже без него связка а-ля элемент + виджет — это «дорогие» и «тяжелые» объекты.

Ответ: С чего вы это взяли? Откуда у вас такие данные? Можно больше данных?


Как раз подобного пытались избежать во Flutter, разделив деревья на 3 параллельных уровня.

Ответ: нет никаких 3-х параллельных деревьев.
Это все статьи сделаны для более простого понимания устройства фреймворка.
Тем более Element есть только у StatefulWidget.

А вот если посмотреть то:
StatefulWidget — это виджет, у него есть State.
В State храниться Element.
BuildContext — это на самом деле и есть наш Element, но в нём при помощи приватных методов скрыта многая функциональность.

А где же RenderObject???

Да вот на самом деле есть ещё RenderObjectWidget и RenderObjectElement. У меня как у программиста нет к ним доступа, так как это приватные классы.

Так вот эти RenderObjectWidget — это наследник Widget, так же как и StatefulWidget.

А вот RenderObject один из филдов в RenderObjectElement. У каждого наследника RenderObject переопределяется метод paint который и вызывает рисование на Canvas.

У Canvas есть native вызовы, которые стучатся в canvas.cc в Flutter Engine.

Так что рассказы про то что в Flutter 3 параллельных дерева — это полный буллщит.
Дерево — это на самом деле не больше чем один большой объект в который вложены другие. там сразу и widget и element и render object.
это вы можете проверить просто вызвав метод debugDumpApp()


А еще в дополнение к этой схеме, слышал вроде бы RN по мосту гоняет данные в JSON формате и при увеличении количества данных, мост начинает проседать.

Ответ: в точку!!!

Если просто, то RN и Flutter очень похожи по концепциям. Когда общался с React разработчиками у себя в компании, то различия очень маленькие. В React/RN есть дом, в Flutter есть дерево виджетов. Ключевая разница в методе отрисовки UI компонентов.

В Flutter есть тоже бриджинг для прокалывания данных: Flutter -> Native -> Skia Canvas.

Но разница в том что Flutter сразу рисует всё на канаве, а вот RN прокидывает данные о UI так: RN -> Native -> Compose Native UI -> Render Native with Skia Android.
Классная статья. Хотел бы ещё уточнить что у каждого элемента есть свой Lifecycle.

/// Tracks the lifecycle of [State] objects when asserts are enabled.
enum _StateLifecycle {
/// The [State] object has been created. [State.initState] is called at this
/// time.
created,

/// The [State.initState] method has been called but the [State] object is
/// not yet ready to build. [State.didChangeDependencies] is called at this time.
initialized,

/// The [State] object is ready to build and [State.dispose] has not yet been
/// called.
ready,

/// The [State.dispose] method has been called and the [State] object is
/// no longer able to build.
defunct,
}


BuildOwner — отвечает за отслеживание, какие виджеты нуждаются в перестройке, и обрабатывает другие задачи это относится к деревьям виджетов в целом, например к управлению списком неактивных элементов для дерева.

Вызов метода setState, приводит к вызову у ElementObject метода markNeedsBuild().
Этот метод в свою очередь помечает ElementObject «dirty». И добавляется в список который хранится в BuildOwner.
_dirty = true;

Далее вызывается метод buildScope у BuildOwner который вызывает RenderObjectToWidgetAdapter. Там происходит вызов метода rebuild у каждого ElementObject который стал dirty.
После этого rebuild вызывает performRebuild в котором происходит проверка canUpdate и вызывается updateChild который в свою очередь возвращает новый ElementObject.

Далее после того как все новые ElementObject были созданы Flutter SDK начинает рендрить новые элементы в редеете всех виджетов.

Про алгоритмы рендеринга можно почитать тут: flutter.dev/docs/resources/inside-flutter
Спасибо что обратили внимание, но к сожалению это не перевод, а личный опыт. Я не скрываю что примерами реализации я вдохновлялся в данной статье, так как по поему мнению это очень хороший пример
К сожалению я не могу перевести продакшен приложение на beta канал. Это может вызвать много проблем
Для того чтобы вы могли использовать extension, вам нужно сделать import. Глобальных extension к сожалению нет.
К сожалению сейчас вы не можете сделать разные проекты с разной версией Dart и вам придётся переключаться (возможно и нет, всё зависит от проекта). Насколько я знаю сейчас команда dart ведёт над этой фичёй разработку. Думаю в ближайшем будущем вы можете указать к каждому проекту определённую версию dart.

на Mac:
brew upgrade dart

на Windows:
choco upgrade dart-sdk

на Linux:
используйте apt-get

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity