После конференции Google многие люди советовались со мнойFlutterСвязанные вопросы, многие из которых связаны с собеседованиями, теперь перечислены в некоторыхFlutterСоответствующие требования, наконец, подумайте об этом или напишите резюме, это можно рассматривать какFlutterэтапный обзор.
⚠️系统完整的学习是必须需要的,这里只能帮你总结一些知识点,更多的还请查阅 Dart/Flutter 官网。
Эта статья в основном представляет собой сводку знаний.Если у вас есть какие-либо вопросы, вы можете щелкнуть ссылки каждой статьи для получения подробной информации или обратиться ко мне.Колонка самородков.
Секция дартс
на самом деле узналJavaScript
илиJava/Kotlin
люди, обучениеDart
Это почти не сложно,Дарт сочетает в себе черты динамических и статических языков,Здесь в основном представлены разные или интересные концепции.
-
1,
Dart
принадлежат дастрого типизированный язык, но вы можете использоватьvar
объявить переменные,Dart
Могусамовыводимый тип данных,var
На самом деле это "синтаксический сахар" времени компиляции.dynamic
Представляет динамический тип, после компиляции, на самом деле являетсяobject
Тип, проверка типов не выполняется во время компиляции, но проверка типов выполняется во время выполнения. -
2,
Dart
серединаif
и т.д. заявление поддерживает толькоbool
Типы,switch
Поддерживается строковый тип. -
3.
Dart
серединамассив иList
это то же самое. -
4.
Dart
середина,Runes
Символический текст, это кодированная строка UTF-32, используемая для E.G.Runes input = new Runes('\u{1f596} \u{1f44d}');
-
5.
Dart
Замыкания поддерживаются. -
6.
Dart
Тип номера делится наint и double , без типа float. -
7.
Dart
серединакаскадный операторВы можете легко настроить логику, следующий код:
event
..id = 1
..type = ""
..actor = "";
- 8. Оператор присваивания
Более интересными операторами присваивания являются:
AA ?? "999" ///表示如果 AA 为空,返回999
AA ??= "999" ///表示如果 AA 为空,给 AA 设置成 999
AA ~/999 ///AA 对于 999 整除
- 9. Дополнительные параметры метода
Dart
метод может быть установлензначение параметра по умолчаниюа такжеуказать имя.
Например:getDetail(Sting userName, reposName, {branch = "master"}){}
метод, если ветвь не задана, по умолчанию используется "мастер". Тип параметра может быть указан или не указан. Эффект вызова:getRepositoryDetailDao(“aaa", "bbbb", branch: "dev");
.
- 10. Объем
Dart
нет ключевых словpublic
,private
модификатор etc,_
Нижнее горизонтальное прямое представлениеprivate
, но есть@protected
Аннотация.
- 11. Метод строительства
Dart
Несколько конструкторов в , которые могут быть реализованы именованными методами.
Может быть только один конструктор по умолчанию, иModel.empty()
Метод может создать класс с пустыми параметрами, на самом деле имя метода любое, а когда переменная инициализирует значение, нужно только передатьthis.name
Вы можете указать его в конструкторе:
class ModelA {
String name;
String tag;
//默认构造方法,赋值给name和tag
ModelA(this.name, this.tag);
//返回一个空的ModelA
ModelA.empty();
//返回一个设置了name的ModelA
ModelA.forName(this.name);
}
- 12, геттер-сеттер переписать
Dart
Все базовые типы, классы и т.д. вObject
, значение по умолчаниюNULL
, приходит сgetter
а такжеsetter
, и еслиfinal
илиconst
, то он имеет только одинgetter
метод,Object
Оба поддерживают перезапись геттера и сеттера:
@override
Size get preferredSize {
return Size.fromHeight(kTabHeight + indicatorWeight);
}
- 13. Утверждать
assert
Действует только в режиме проверки, во время разработки, assert(unicorn == null);
Это нормально, только если условие истинно, в противном случае сразу бросается исключение, которое обычно используется в процессе разработки, и в некоторых местах не должно быть никакого государственного суждения.
- 14. Перепишите оператор, перегрузив его, как показано ниже.
operator
+/- операции над классом потом.
class Vector {
final int x, y;
Vector(this.x, this.y);
Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
Vector operator -(Vector v) => Vector(x - v.x, y - v.y);
···
}
void main() {
final v = Vector(2, 3);
final w = Vector(2, 2);
assert(v + w == Vector(4, 5));
assert(v - w == Vector(0, 1));
}
Операторы, поддерживающие перегрузку:
- класс, интерфейс, наследование
Dart
В классе нет интерфейса, и все классы можно использовать как интерфейсы, при реализации класса как интерфейса нужно использовать толькоimplements
, а затем переопределить метод родительского класса.
Dart
средняя поддержкаmixins
, в порядке появления должно быть extends
,mixins
,implements
.
-
Zone
Dart
пройти вZone
Представляет среду, в которой выполняется указанный код, аналогично концепции песочницы, вFlutter
серединаC++бегатьDart
Также в_runMainZoned
выполнить в течениеrunZoned
метод запускается, и мы также можем передатьZone
, для сбора информации, такой как глобальные исключения в среде выполнения:
runZoned(() {
runApp(FlutterReduxApp());
}, onError: (Object obj, StackTrace stack) {
print(obj);
print(stack);
});
При этом вы можете датьrunZoned
Зарегистрируйте метод и при необходимости выполните обратный вызов, как показано в следующем коде, чтобы вZone
в любом месте в пределахonData
этоZoneUnaryCallback
, вы можете позвонить вhandleData
///最终需要处理的地方
handleData(result) {
print("VVVVVVVVVVVVVVVVVVVVVVVVVVV");
print(result);
}
///返回得到一个 ZoneUnaryCallback
var onData = Zone.current.registerUnaryCallback<dynamic, int>(handleData);
///执行 ZoneUnaryCallback 返回数据
Zone.current.runUnary(onData, 2);
Асинхронная логика может быть реализована черезscheduleMicrotask
Асинхронные методы выполнения могут быть вставлены:
Zone.current.scheduleMicrotask((){
//todo something
});
Больше можно найти по адресу:«Полная разработка Flutter и подробное объяснение фактического боя (11, всестороннее и глубокое понимание Stream)»
-
Future
Future
Проще говоря, правильноZone
пакет используется.
НапримерFuture.microtask
в основном реализованоZone
изscheduleMicrotask
,а такжеresult._complete
Последний звонок_zone.runUnary
и т.п.
factory Future.microtask(FutureOr<T> computation()) {
_Future<T> result = new _Future<T>();
scheduleMicrotask(() {
try {
result._complete(computation());
} catch (e, s) {
_completeWithErrorCallback(result, e, s);
}
});
return result;
}
Dart
пройти вasync
/await
илиFuture
определяют асинхронные операции, а на самом делеasync
/await
Это также просто синтаксический сахар, который в конечном итоге преобразуется компилятором вFuture
.
Интересно посмотреть здесь:
-
Stream
Stream
да даZone
Используется другой пакет.
Еще одна асинхронная операция в Dart,async*
/ yield
илиStream
поддающийся определениюStream
асинхронный,async*
/ yield
Это также просто синтаксический сахар, который в конечном итоге преобразуется компилятором вStream
.
Stream также поддерживает синхронные операции.
1),Stream
в основном включаютStream
,StreamController
,StreamSink
а такжеStreamSubscription
Четыре ключевых объекта можно приблизительно резюмировать следующим образом:
-
StreamController
: как следует из названия класса, для всегоStream
Управление процессом, предоставляющее различные интерфейсы для создания различных потоков событий. -
StreamSink
: обычно используется в качестве входа на мероприятие, обеспечивая, например,add
,addStream
Ждать. -
Stream
: сам источник событий, который обычно можно использовать для мониторинга событий или преобразования событий, напримерlisten
,where
. -
StreamSubscription
: объект после подписки на событие, который якобы используется для управления различными операциями, такими как подписка, напримерcacenl
,pause
, и в то же время это также ключ к транзиту событий внутри.
2),обычно проходятStreamController
СоздайтеStream
;пройти черезStreamSink
добавить событие; передатьStream
слушать события; проходитьStreamSubscription
Управление подписками.
3),Stream
поддерживает различные изменения, такие какmap
,expand
,where
,take
и другие операции, поддерживая преобразование вFuture
.
Больше можно найти по адресу:«Полная разработка Flutter и подробное объяснение фактического боя (11, всестороннее и глубокое понимание Stream)»
Флаттер раздел
Основное различие между Flutter и React Native заключается в том, чтоПользовательский интерфейс Flutter рендерится напрямую с помощью skia, а React Native преобразует элементы управления в js в собственные элементы управления и отображает их нативно., для получения дополнительной информации см.:"Углубленный анализ мобильной кроссплатформенной разработки".
-
существует во флаттере
Widget
,Element
,RenderObject
,Layer
четыре дерева, из которыхWidget
а такжеElement
это отношение один ко многим, -
Element
проводится вWidget
а такжеRenderObject
, а такжеElement
а такжеRenderObject
является взаимно-однозначным соответствием (исключаяElement
не существуетRenderObject
ситуация, напримерComponentElement
не доступенRenderObject
), -
когда
RenderObject
изisRepaintBoundary
дляtrue
, то области образуютLayer
,такне каждыйRenderObject
как естьLayer
, потому что этоisRepaintBoundary
Влияние.
-
Во трепете
Widget
Неизменный, остается один кадр за раз, еслиизменение происходит черезState
Реализуйте кросс-фреймовое хранилище,а такжеЧто на самом деле делает макет и рисунок массиваRenderObject
,Element
действовать как мост между ними,State
хранится вElement
середина. -
во флаттере
BuildContext
только интерфейс, аElement
понял это. -
Во трепете
setState
На самом деле называетсяmarkNeedsBuild
, внутри методаотметить этоElement
дляDirty
, то на следующем кадреWidgetsBinding.drawFrame
будет нарисовано, что видноsetState
Не действует сразу. -
Во трепете
RenderObject
существуетattch
/layout
пройдет позжеmarkNeedsPaint();
Процесс перерисовки страницы примерно следующий:
Область обновления определяется isRepaintBoundary, а обновление запускается методом requestVisualUpdate для прорисовки.
- нормальные обстоятельства
RenderObject
Последовательность вызова метода, связанного с компоновкой:layout
->performResize
->performLayout
->markNeedsPaint
,Однако пользователи обычно не вызывают напрямуюlayout
, нопройти черезmarkNeedsLayout
, конкретный процесс выглядит следующим образом:
-
Генерал во флаттереjsonданные из
String
Перевести вObject
процесс должен пройти сначалаMap
Типы. -
Во трепете
InheritedWidget
обычно используется длясовместное использование состояния,Такие какTheme
,Localizations
,MediaQuery
и т. д., все это для достижения общего состояния, чтобы мы могли передатьcontext
Чтобы получить общее состояние, напримерThemeData theme = Theme.of(context);
существует
Element
изinheritFromWidgetOfExactType
В реализации метода естьMap<Type, InheritedElement> _inheritedWidgets
Объект.
_inheritedWidgets
Обычно пустой, только если родительский элемент управленияInheritedWidget
или самInheritedWidgets
будет инициализирован, когда родительский элемент управленияInheritedWidget
когда этоMap
Он будет передаваться и объединяться уровень за уровнем.поэтому, когда мы проходим
context
передачаinheritFromWidgetOfExactType
, вы можете подняться, чтобы найти родительский контрольWidget
.
- По умолчанию во Flutter в основном через
runtimeType
а такжеkey
Обновление приговора:
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
}
Жизненный цикл во Flutter
-
initState()
Указывает текущийState
будет иBuildContext
связаны, но в настоящее времяBuildContext
Не полностью загружен, если вам нужно попасть в этот методBuildContext
,Могуnew Future.delayed(const Duration(seconds: 0, (){//context});
один раз.
Точнее, его теперь следует использовать
SchedulerBinding
-
didChangeDependencies()
существуетinitState()
после звонка, когдаState
Этот метод вызывается при изменении зависимостей объекта, а также при его инициализации. -
deactivate()
когдаState
Этот метод вызывается при временном удалении из дерева просмотра, а также вызывается при переключении страницы. (исчезла в новой версии) -
dispose()
Виджет уничтожается, перед вызовом этого метода всегда вызывается функция deactivate(). -
didUpdateWidge
когдаwidget
Вызывается при изменении состояния.
-
пройти через
StreamBuilder
а такжеFutureBuilder
мы можем быстро использоватьStream
а такжеFuture
Быстро создайте наш асинхронный элемент управления:«Полная разработка Flutter и подробное объяснение фактического боя (11, всестороннее и глубокое понимание Stream)» -
Во трепете
runApp
Начальная запись на самом деле являетсяWidgetsFlutterBinding
, в основном черезBindingBase
подклассGestureBinding
,ServicesBinding
,SchedulerBinding
,PaintingBinding
,SemanticsBinding
,RendererBinding
,WidgetsBinding
подожди, черезmixins
комбинация . -
Нити дротика во FlutterЦикл событий и очередь сообщенийсуществует в виде двух очередей задач,Одна — внутренняя очередь микрозадачи, другая — внешняя очередь события, причем приоритет микрозадачи выше, чем событие.
Так как приоритет микрозадачи выше, чем событие, и она одновременно блокирует очередь событий, поэтому, если микрозадач слишком много, это может привести к блокировке и задержке внешних событий, таких как касание и рисование.
- существует во флаттереЧетыре потока соответственно
UI Runner
,GPU Runner
,IO Runner
,Platform Runner
(родной основной поток), а во Flutter можно пройтиisolate
илиcompute
Выполнение настоящих асинхронных операций между потоками.
PlatformView
Прошел во флаттереPlatformView
может быть вложенным изначальноView
прибытьFlutter
В пользовательском интерфейсе это фактически используетсяPresentation
+ VirtualDisplay
+ Surface
И так далее, общий принцип:
Используя технологию, аналогичную отображению вторичного экрана,VirtualDisplay
класс представляет виртуальный дисплей, вызовDisplayManager
изcreateVirtualDisplay()
метод, который отображает содержимое виртуального дисплея вSurface
контроль, а потомSurface
Идентификатор сообщается Dart, поэтому, когда движок рисует, он находит соответствующий идентификатор в памяти.Surface
Затем рисуются данные памяти экрана. Эм...Технология отображения рендеринга скриншотов управления в реальном времени.
-
Режим отладки Flutter — это режим JIT, а режим выпуска — режим AOT.
-
Во Flutter вы можете пройти
mixins AutomaticKeepAliveClientMixin
, затем перепишитеwantKeepAlive
Держите страницу, не забывайте быть на удерживаемой страницеbuild
вызыватьsuper.build
. (Потому что характеристики миксинов). -
События жестов флаттера в основном оцениваются по соревнованиям:
ЕстьhitTest
Все элементы управления, которые необходимо обработать, соответствуютRenderObject
, отchild
прибытьparent
Все они объединены в список, добавленный от самого внутреннего к самому внешнему.
Затем запустите выполнение цикла for из дочернего элемента в начале очереди.handleEvent
метод, выполнитьhandleEvent
Процесс не будет прерван перехватом.
При обычных обстоятельствах событие Down не определяет победителя.В большинстве случаев победитель определяется, когда происходит событие MOVE или UP.
Когда арена закрыта, только один напрямую выиграет ответ, а если победителя нет, то первый в очереди будет вынужден выиграть ответ.
ТакжеdidExceedDeadline
Обрабатывать событие Down при нажатии и удерживать дополнительную обработку, в то время как обработка жестов обычно включенаGestureRecognizer
подкласс.
Для получения более подробной информации, пожалуйста, проверьте:«Полная разработка флаттера и подробное объяснение фактического боя (тринадцать, всестороннее подробное касание и принцип скольжения)»
-
Во трепете
ListView
Скольжение на самом деле происходит за счет измененияViewPort
серединаchild
Макет для достижения отображения. -
Обычно используемое государственное управление: в настоящее время есть
scope_model
,flutter_redux
,fish_redux
,bloc + Stream
Доступно несколько других режимов, которые можно увидеть в деталях:«Полная разработка Flutter и подробное объяснение реального боя (12, всестороннее и глубокое понимание дизайна управления состоянием)»
Platform Channel
Во Flutter вы можете пройтиPlatform Channel
Позвольте коду Dart взаимодействовать с собственным кодом:
BasicMessageChannel
: Используется для передачи строк и полуструктурированной информации.MethodChannel
: Используется для передачи вызова метода.EventChanne
l: для связи с потоками событий.
в то же времяPlatform Channel
не потокобезопасный, для получения более подробной информации см. Xianyu Technology"Глубокое понимание канала платформы Flutter"
Базовые типы данных отображаются следующим образом:
Заставка Android
в AndroidFlutter
По умолчанию он начинается сFlutterActivityDelegate.java
Читать внутри AndroidManifset.xmlmeta-data
ярлык, которыйio.flutter.app.android.SplashScreenUntilFirstFrame
Если бит флага равен true, запустится эффект экрана-заставки (аналогично стартовой странице IOS).
Собственный код будет читаться при запускеandroid.R.attr.windowBackground
уточнитьDrawable
, используемый для отображения эффекта заставки, а затем передатьflutterView.addFirstFrameListener
,существуетonFirstFrame
Удалить заставку в .
Ну это все пока здесь, если будут какие-то проблемы, то это будет исправлено или дополнено, а я добавлю позже.
Рекомендация ресурса
- Гитхаб:github.com/CarGuo
- Полный проект Flutter с открытым исходным кодом:GitHub.com/car GU O/GS YG…
- Учебный проект Flutter с открытым исходным кодом для нескольких случаев:GitHub.com/car GU O/GS YF…
- Проект практической электронной книги Flttre с открытым исходным кодом:GitHub.com/car GU O/GS YF…