Введение в Dart
В модуле рассматривается синтаксис языка Dart (с учетом Null Safety и новых конструкций последней версии Dart) и инструментальные средства компиляции и анализа приложений, создания и установки пакетов.
Введение в язык программирования Dart
писать корректный код на dart, используя базовые конструкции и систему типов;
проектировать и объявлять функции (позиционные/именованные параметры, значения по умолчанию);
применять null-safety в сигнатурах и реализациях;
использовать стандартную библиотеку для работы со строками, числами и коллекциями.
Алгоритмы на языке Dart
подбирать и применять структуры данных (list/set/map, очереди/кучи, деревья, графы) под задачу;
оценивать асимптотику по времени и памяти и принимать решения с учётом ограничений;
реализовывать и тестировать типовые алгоритмы (поиск, сортировки, обходы деревьев/графов) в идиомах dart;
использовать алгоритмические приёмы и простые паттерны для расширяемых решений.
Объектно-ориентированное программирование на Dart
моделировать предметную область через классы, интерфейсы и композицию;
использовать миксины и расширения для повторного использования поведения;
проектировать устойчивые api классов (именованные и factory-конструкторы, инкапсуляция);
описывать конечные состояния через sealed-иерархии и pattern matching.
Инструментальная поддержка Dart
настраивать статический анализ и правила качества кода;
управлять зависимостями и версиями, обеспечивать воспроизводимость сборок;
понимать различия jit/aot и собирать артефакты под mobile/web/desktop;
диагностировать ошибки и эффективно работать с ide/cli.
ДЗ
Создание интерпретатора математических выражений с поддержкой переменных.
План работы:
1. Разработать алгоритм разбора строки с учетом приоритета операций (при необходимости можно вносить изменения в строку)
2. Реализовать функцию (итеративную или рекурсивную) для выполнения последовательности операций
3. Создать класс для вычисления значения произвольной функции с заданными значениями переменных
4. Написать тесты с проверкой результата на выражениях, содержащих операции и их сочетания (например, 2+3*4)
5. Опционально сделать поддержку унарного минуса (например, в выражении -3+5)
Преобразователь должен быть оформлен как класс (конструктор принимает строку с математической функцией) с методом преобразования, принимающим Map с переменными (ключ - название переменной, значение - числовое значение, которое подставляется вместо переменной) и возвращающей значение типа double.
При вычислении значения выражения необходимо учитывать приоритет математических операций. За основу можно взять любой алгоритм (например, https://dev.to/brunooliveira/writing-a-mathematical-expression-evaluator-in-java-1ka6), либо разработать собственный. Для тестирования корректности можно использовать минимум три выражения (x=10).
1) 10*5+4/2-1 (результат 51)
2) (x*3-5)/5 (результат 5)
3) 3*x+15/(3+2) (результат 33)
Должно быть создано не менее 5 тестов (обязательно должны быть тесты на сочетание операций и на использование скобок). Если поддерживается унарный минус, то тесты должны быть сделаны и на эти выражения.
Опционально можно сделать поддержку отрицательных констант с унарным минусом.
### Рекоменуем для начала проверить решение в тренажере, далее по готовности прислать ссылку на github в чат по ДЗ.
Flutter Framework
В модуле подробно изучаются виджеты разметки, ввода информации и отображения содержания в Flutter, архитектурные подходы к декомпозиции виджетов и выделению бизнес-логики, разбираются алгоритмы определения и обработки жестов, особенности разработки Desktop (для Windows, Linux и MacOS) и Web-приложений.
Концепция реактивного пользовательского интерфейса, основные графические примитивы ui.Window
понимать принципы реактивной модели: ui = f(состояние), однонаправленный поток данных;
декомпозировать интерфейс на состояние, представление и источники событий;
построить простой реактивный интерфейс без flutter framework, используя dart:ui/ui.window;
учитывать кадровый бюджет (60/120 гц) и избегать блокировки главного потока.
Анатомия отрисовки виджетов
понимать архитектуру триады widget–element–renderobject и этапы пайплайна (build → layout → paint → composite);
диагностировать и сокращать лишние перестроения и перерисовки с помощью devtools;
корректно работать с buildcontext и зависимостями (inheritedwidget, theme, mediaquery);
применять ключи (key) для сохранения идентичности элементов и устойчивой работы списков.
ДЗ
Размещение объектов по вертикали .
План работы:
1. Создать простой менеджер размещения, который будет использовать информацию о размере, полученную от объектов (с учетом родительских ограничений) для размещения вертикально на экране (левый край объектов должен быть расположен по одной линии)
2. Написать функцию main с привязкой к ui.window (или WidgetsBinding.instance.platformDispatcher.views.first) для расположения не менее 3-х объектов. В качестве объектов можно использовать как простые примитивы (например, цветной прямоугольник), так и растровые изображения
3. Внешними ограничениями для менеджера размещения должны быть (0,0) в качестве минимального размера и размер экрана (WidgetsBinding.instance.platformDispatcher.views.first.physicalSize) как максимальный размер
Понятие и жизненный цикл виджета
различать stateless и stateful и выбирать уместный тип по задаче;
применять методы жизненного цикла state (initstate, didchangedependencies, didupdatewidget, dispose) корректно;
управлять ресурсами и подписками (контроллеры, таймеры, streamsubscription, тикеры) в рамках жизненного цикла;
диагностировать причины лишних перестроений и перерисовок.
Консультация: что внутри Flutter Framework и почему он устроен так
уточнить ментальную модель flutter: роли слоёв (widget/element/renderobject) и их взаимодействие;
разобрать типичные причины лишних перестроений/перерисовок и способы их предотвращения;
отработать диагностику в devtools на реальных кейсах (кадровый бюджет, rebuild/render hotspots);
сверить практики работы с buildcontext, ключами и жизненным циклом с best practices.
Базовые виджеты содержания (текст, изображения, пиктограммы). Составные виджеты. Виджеты разметки
использовать базовые и составные виджеты для отображения содержания (text, image, icon, card, listtile);
проектировать разметку экрана с помощью flex/row/column/stack/flow и понимать boxconstraints;
делать адаптивную верстку с layoutbuilder и корректной иерархией отступов/декораций;
минимизировать лишние перестроения и перерисовки при построении ui.
Виджеты разметки. Создание прокручиваемых виджетов.
проектировать прокручиваемые интерфейсы на базе scrollview и семейства sliver-*;
правильно выбирать контейнеры прокрутки (singlechildscrollview, customscrollview, nestedscrollview) под задачу;
управлять поведением прокрутки: контроллеры, физика, сохранение положения;
снижать jank и лишние перерисовки в длинных списках и сложных лейаутах.
ДЗ
Создание страницы списка рецептов.
Дизайн приложения: [****тут****](https://www.figma.com/file/alUTMeT3w9XlbNf3orwyFA/Otus-Food-App?node-id=135%3A691) (эскизы с возможностью получить цвета, размеры и отступы)
и [**тут** ](https://www.figma.com/proto/alUTMeT3w9XlbNf3orwyFA/Otus-Food-App?node-id=102%3A3&scaling=scale-down&page-id=0%3A1&starting-point-node-id=135%3A691) (навигация по приложению)
План работы:
1. Использовать StatelessWidget с получением в качестве аргумента конструктора списка объектов с описанием блюд
2. Список блюд создать в соответствии со схемой данных с сервера (https://app.swaggerhub.com/apis/dzolotov/foodapi/0.2.0), для доступа к списку нужно реализовать класс менеджера, который в дальнейшем будет изменен для использования данных с сервера (сейчас метод менеджера getRecipes будет возвращать список List<Recipe> и использовать константный список, размещенный внутри менеджера).
3. Выполнить верстку страницы списка рецептов и связать ее с менеджером
4. Сделать эту страницу точкой входа в приложение в обертке MaterialApp - Scaffold (в runApp), изменить цвета темы оформления в MaterialApp для соответствия дизайну
Виджеты ввода информации, работа с формами. Часть 1
обрабатывать пользовательский ввод и жесты (pointer → gesture, gesture arena);
создавать формы и поля ввода с базовой валидацией;
управлять фокусом и клавиатурой (переключение полей, скрытие/показ);
настраивать визуальную обратную связь полей (состояния, ошибки, подсказки).
Виджеты ввода информации, работа с формами. Часть 2
реализовывать сложные формы: маски ввода, форматтеры, зависимые поля, отправка и сброс;
организовывать валидацию (в т.ч. отложенную/асинхронную) и отображение ошибок без «дребезга»;
управлять фокусом в сценариях многошагового ввода и навигации по полям;
повышать стабильность и отзывчивость форм в реальных сценариях (длинные списки, частые апдейты).
Визуальное оформление (расширение темы), шрифты, градиенты и шейдеры, использование возможностей Impeller
настраивать дизайн-систему через тему и расширения темы;
подключать и использовать шрифты, управлять типографикой и масштабированием текста;
создавать визуальные эффекты: градиенты, тени/свечения, маски и шейдеры;
учитывать производительность рендеринга (Impeller/Skia) и избегать shader-jank.
Практика по реализации сложной верстки. Навигация и уведомления
сверстать сложный экран/набор экранов по макету с адаптацией под разные устройства;
настроить навигацию со стеком, вложенными маршрутами и модальными диалогами;
организовать ненавязчивые in-app уведомления (snackbar/banner/dialog) в сценариях ux;
профилировать сцену и снизить jank на длинных списках и анимированных переходах.
ДЗ
Создание страницы для добавления нового рецепта.
Дизайн приложения: [****тут****]( https://www.figma.com/file/alUTMeT3w9XlbNf3orwyFA/Otus-Food-App?node-id=135%3A691) (эскизы с возможностью получить цвета, размеры и отступы)
и [**тут** ](https://www.figma.com/proto/alUTMeT3w9XlbNf3orwyFA/Otus-Food-App?node-id=102%3A3&scaling=scale-down&page-id=0%3A1&starting-point-node-id=135%3A691) (навигация по приложению)
План работы:
1. Использовать StatefulWidget для верстки формы заполнения данных о новом рецепте
2. Добавить в менеджер возможность получения списка ингредиентов и единиц измерения (схема аналогично API из документации https://app.swaggerhub.com/apis/dzolotov/foodapi/0.2.0), которые будут использовать для добавления шагов и ингредиентов
3. Расширить модель описания рецепта (добавить список ингридиентов и шаги приготовления)
4. Реализовать дополнительные формы для ввода информации о новом ингредиенте и новом шаге (с использованием модального диалога)
5. Сейчас не нужно реализовывать загрузку фотографии, но вместо нее разместить виджет Placeholder
6. Дополнить менеджер списка рецептов из предыдущего домашнего задания методом для сохранения нового рецепта (в дальнейшем реализация будет заменена на работу с сетевым API)
7. Выполнить верстку страницы добавления рецепта и связать ее с менеджером, при наличии ошибок валидации отображать их в соответствующих текстовых полях (стандартными методами TextField)
8. Сделать обновление списка рецептов после завершения добавления (нужно использовать внешний StatefulWidget вокруг списка рецептов и обновлять его после выполнения добавления)
9. Сделать переход в страницу добавления рецепта по кнопке из списка рецентов (с использованием Navigator.push)
Лучшие архитектурные практики для создания приложений
строить слоистую архитектуру (ui / domain / data) с чётким разделением ответственности;
связывать реактивный ui с источниками данных и событиями без «протечек» зависимостей;
выбирать и применять уместный менеджмент состояния (provider/riverpod/bloc) на уровне фич;
закладывать наблюдаемость, тестируемость и правила качества в архитектурные решения.
Выбор темы и организация проектной работы
сформулировать тему и ключевые пользовательские сценарии проекта;
спроектировать базовую архитектуру (слои, навигация, состояние) и критерии готовности;
определить правила качества (линты, диагностика, метрики) и рабочее окружение;
разбить работу на инкременты и запланировать вехи (mvp → расширения).
ДЗ
Курсовой проект.
1. Выбрать тему для курсового проекта
2. Указать тему через кнопку "Предложить тему"
3. Продумать и описать функциональность приложения (должно быть не менее 3 экранов, подключение к сетевому API, можно использовать публичный, локальное хранение, анимации переходов). Также в приложении должно быть предусмотрено взаимодействие с платформенным кодом (например, для определения режима энергосбережения)
4. Разработать необходимые виджеты (с использованием тестовых данных)
5. Реализовать бизнес-логику (контроллеры, объекты хранения состояния или иные, связанные с выбранным подходом к управлению состоянием)
6. Создать тесты для бизнес-логики и виджетов
7. Выполнить сборку aab-артефакта и отправить его в проект (в личном кабинете, в чате этого домашнего задания), а также отправить ссылку на github
Кроссплатформенная разработка для Web
собрать и запустить приложение под web, понимать ограничения и отличия от мобильных таргетов;
корректно обрабатывать ввод и жесты в браузере, применять pointerinterceptor в сложных сценах;
выполнять базовую интероперабельность с javascript через dart:js;
учитывать требования к производительности и размеру бандла при поставке web-версии.
ДЗ
Адаптация для браузера .
План работы:
1. Использовать OrientationBuilder и при использовании горизонтальной ориентации в формах использовать ограничение ширины в 50%
2. Если в коде были использованы методы dart:io, сделать доработки для возможности использования в веб (можно использовать универсальный плагин universal_io)
3. Скомпилировать приложение в Web и добавить архив из build/web в github-репозиторий в виде архива
Кроссплатформенная разработка для Desktop
собрать и запустить приложение под windows/linux/macos, понимать отличия от мобильных таргетов;
учитывать оконность: ресайз, многоэкранность, клавиатура/мышь, системные шорткаты и фокус;
интегрироваться с нативной средой: доступ к файловой системе, диалогам, системным сервисам (через ffi/каналы);
подготовить артефакты поставки (release-сборка) и проверить производительность/стабильность.
Низкоуровневое рисование с использованием сцены и возможностей Canvas.
понимать модель слоёв и сцены: layout/paint/composite, scene/layer;
выполнять кастомную отрисовку через canvas/custompainter и управлять областью перерисовки;
делать оффскрин-рендеринг и кеширование (например, через picturerecorder/toimage);
профилировать графику и избегать jank (учёт impeller/skia, осторожное savelayer/клиппинг).
ДЗ
Создание страницы описания рецепта с возможностью переключения отметки избранного и шагов приготовления.
Дизайн приложения: [**тут** ](https://www.figma.com/file/alUTMeT3w9XlbNf3orwyFA/Otus-Food-App?node-id=135%3A691) (эскизы с возможностью получить цвета, размеры и отступы) и [**тут**](https://www.figma.com/proto/alUTMeT3w9XlbNf3orwyFA/Otus-Food-App?node-id=102%3A3&scaling=scale-down&page-id=0%3A1&starting-point-node-id=135%3A691) (навигация по приложению)
План работы:
1. Сделать верстку страницы (StatefulWidget) с описанием рецепта
2. Реализовать переключение кнопки ""Избранное"" (для создания кнопки использовать возможности canvas с Path и кривыми)
3. Расширить менеджер возможностью сохранения комментариев и отметки ""Избранное""
4. Реализовать переключение отметки шагов приготовления (checkbox)
5. Возможность добавить комментарий к рецепту (текстовое поле + кнопка + изменение состояния для отображения нового комментария после добавления)
Консультация по ДЗ + практика
ответить на вопросы по темам модуля и по дз/проекту;
закрепить разметку, прокрутку, ввод/формы и навигацию на практических задачах;
отработать диагностику производительности и устранение лишних перестроений/перерисовок;
сформировать индивидуальный план улучшений для проектной работы.
Асинхронность и сетевое взаимодействие
В модуле разбираются способы генерации исходных текстов по описанию модели данных или сетевого API, библиотеки для локального хранения данных и обмена информацией по сети, а также архитектура приложений для Firebase, Auth0 и сервисов Google.
Асинхронность в Dart, потоки и Future
понимать модель event loop и различия future/stream, уместно применять async/await;
проектировать асинхронные api с корректной обработкой ошибок, таймаутов и отмены;
управлять подписками (streamsubscription) и жизненным циклом асинхронных операций;
связывать асинхронные данные с ui через futurebuilder/streambuilder без лишних перестроений.
Сетевое взаимодействие, хранение данных на устройстве
собрать слой api на основе http-клиента с централизованной обработкой ошибок и ретраев;
выбрать и применить локальное хранилище (kv/объектное/реляционное), настроить кэш;
реализовать авторизацию: хранение и обновление токена, безопасное взаимодействие с сессией;
связать сеть и хранилище с ui асинхронно, избегая блокировок главного потока.
Использование кодогенерации во Flutter. Сериализация данных в JSON. Создание неизменяемых классов.
проектировать модели данных и контракты api (dto ↔ entity) для устойчивой сериализации;
настраивать кодогенерацию (build_runner) и применять json_serializable/freezed;
создавать неизменяемые модели с copywith/сравнением по значению и union-типами для ui-состояний;
покрывать модели тестами сериализации и совместимости полей.
ДЗ
Получение информации о рецептах от сервера через http, локальное хранение данных.
План работы:
1. Подготовить модель данных для локального хранения информации о рецептах для Hive (список рецептов извлекается из коллекции, отдельный объект коллекции - рецепт, внутри него сохраняется информация об ингридиентах/шагах приготовления)
2. Реализовать API-запросы для получения списка рецептов, информации о рецепте, изображения (можно использовать Dio или кодогенерацию), добавления нового рецепта и связывания шагов/ингредиентов в соответствии с API (https://app.swaggerhub.com/apis/dzolotov/foodapi/0.2.0)
3. При отсутствии Интернета использовать локальные данные вместо API (можно использовать flutter_network_connectivity или аналог)
4. Изменить менеджер доступа к информации о рецептах и создания новых рецептов на поддержку сетевых запросов или локального хранилища
5. В любом случае сохранить полученные данные в локальную базу данных через Hive и отправить в API (если интернет доступен)
Апи для получения рецептов доступно по ссылке - https://foodapi.dzolotov.tech
Интеграция с внешними API и бессерверные приложения
подключать облачные сервисы (firebase/auth0) и внешние sdk (maps/webview) с учётом безопасности и производительности;
реализовать аутентификацию и push-уведомления, фиче-флаги/remote config и аналитику;
изолировать сторонние sdk через адаптеры/интерфейсы для тестируемости и независимости ui;
настроить разрешения и платформенные настройки (android/ios/web) без блокировки ui.
Консультация по ДЗ + практика
ответить на вопросы по асинхронности, моделям/кодгену, сети/хранилищу и интеграциям;
закрепить паттерны: future/stream, freezed/json_serializable, dio+retrofit, кэш offline-first;
отладить аутентификацию, пуши, remote config, карты/webview; проверить разрешения и deeplink;
зафиксировать метрики производительности и стабильности (до/после) по практическому сценарию.
Анимация и мультимедиа в Flutter
В модуле рассматриваются вопросы создания визуальной привлекательности приложений (через программные и внешние анимации, игровые элементы) и работы с мультимедиа (камерой, звуком, видео).
Неявные анимации во Flutter, Hero-анимации
применять неявные анимации (animated* и tweenanimationbuilder) для плавных изменений состояния без контроллеров;
использовать hero для межэкранных переходов: корректные теги, placeholder/flight-настройки, отсутствие «телепорта»;
снижать лишние перестроения при анимациях за счёт грамотной области обновлений и repaintboundary;
профилировать анимации, удерживая кадровый бюджет, и фиксить jank с помощью devtools.
Явные анимации во Flutter, переходы между страницами. Управление анимацией. Кривые.
создавать явные анимации с использованием animationcontroller, tickerprovider, curvedanimation, tween/sequence/staggered;
реализовывать переходы между экранами через кастомные pageroute/pagetransitionsbuilder;
управлять ресурсами анимаций (инициализация, dispose, предотвращение утечек тикеров);
профилировать анимации и удерживать кадровый бюджет без лишних перестроений.
ДЗ
Создание анимаций перехода между страницами, анимаций для переключения шагов рецепта.
План работы:
1. добавить переход между страницами по умолчанию FadeTransition
2. реализовать анимацию изменения состояния чекбокса и сделать ее программно управляемой (через Explicit Animation), можно использовать два виджета и AnimatedCrossFade
3. присоединить запуск анимации в прямом и обратном направлении на событие перехода чекбокса (включение, выключение)
Игровые движки во Flutter. Создание 3D-анимации.
реализовать простой игровой цикл на базе игрового движка (например, flame): сцена, спрайты, анимации, ввод;
настроить управление ресурсами: загрузка ассетов, аудио, столкновения/физика на уровне фич;
интегрировать 3d/высокопроизводительную графику: подключение webgl-контекста в web и специализированных плагинов;
профилировать производительность рендеринга и удерживать кадровый бюджет в игровых сценариях.
Интеграция сторонних анимаций во Flutter-приложение.
подключать и воспроизводить анимации rive/lottie/svg; управлять состояниями и таймлайном;
связывать анимации с состоянием ui (idle/loading/success/error) и пользовательскими событиями;
оптимизировать размер и производительность ассетов (сложность векторной сцены, кэширование, фреймрейт);
диагностировать и устранять jank при воспроизведении анимаций.
Поддержка мультимедиа и камеры во Flutter. Обработка изображений, распознавание и классификация.
получать разрешения и доступ к камере/микрофону; выполнять захват фото/видео и предпросмотр;
интегрировать библиотеки машинного зрения (например, tensorflow lite) для распознавания/классификации на устройстве;
реализовывать синтез речи (tts) и обработку медиапотоков в ui;
обеспечивать производительность и стабильность медиапайплайна (память, кадры, задержки).
ДЗ
Добавление снимков с камеры и идентификация объектов на сцене.
План работы:
1. Подключить внешнюю анимацию для пиктограммы избранного (несколько пульсаций, необходимо реализовать в Rive)
2. Реализовать получение изображения с камеры (действие ""добавить изображение в рецепт""), сохранить его в локальную базу данных и отобразить на странице рецепта галерею (с возможностью полноэкранного просмотра)
3. Изображение с камеры/галереи использовать как источник для детектирования объектов. После выбора изображения (создания фотографии или выбора изображения через плагин image_picker) применить модель SSD MobileNet v1 с помощью Tensorflow Lite (плагин tflite_v2 или tflite_flutter) и обнаружить top5 наиболее вероятных объектов (по аналогии с https://www.tensorflow.org/lite/examples/object_detection/overview), названия и вероятности объектов сохранить в изображении (нарисовать поверх)
Интернационализация и доступность
локализовать приложение с использованием intl/arb: организация ресурсов, plural/gender, форматирование дат/чисел/валют;
обеспечивать доступность: семантическая разметка виджетов, корректная работа экранных дикторов, порядок фокуса и навигации;
поддерживать rtl-направление, учитывать textscalefactor и особенности шрифтов/языков;
диагностировать и тестировать доступность с помощью платформенных средств и semantics-инструментов.
Консультация по ДЗ + практика
разобрать вопросы по анимациям, i18n/a11y, мультимедиа и игровым сценам;
закрепить паттерны: неявные/явные анимации, hero и кастомные переходы;
отработать интеграцию rive/lottie/svg и проверку доступности/локализации;
профилировать и оптимизировать сцену: устранить jank, сократить лишние перерисовки.
Архитектура приложений, управление состоянием и навигация
Модуль полностью посвящен рассмотрению архитектурных подходов к управлению состоянием приложений и реализации навигации между страницами (подходы Navigator и Router).
Inherited-виджеты. Библиотеки Provider и Riverpod.
понимать модель контекста и распространения состояния через inheritedwidget;
применять provider/riverpod для хранения и чтения состояния на уровне фич;
снижать лишние перестроения с помощью consumer/selector и точечного watch/read;
тестировать состояние через переопределения провайдеров и фейковые реализации.
Clean-архитектура. Реализация инъекции зависимостей (getit, Provider/Riverpod)
строить слоистую архитектуру (ui / domain / data) с чёткими границами и направлением зависимостей;
внедрять зависимости через контейнер (get_it) и/или провайдеры (provider/riverpod), управлять жизненным циклом (singleton/lazy/factory);
изолировать платформенный и внешние sdk через интерфейсы/адаптеры для тестируемости и замены реализаций;
организовывать «проводку» приложения: точка входа, окружения (dev/stage/prod), конфигурация на старте;
ДЗ
Многоязычный интерфейс и принципы чистой архитектуры .
План работы:
1. Добавить библиотеку (любую из доступных на pub.dev) для поддержки переключения языков и перенести все строковые константы в нее.
2. Предусмотрить возможность переключения языка в приложении (строки на другом языке создавать не требуется)
3. Подготовить структуру проекта в соответствии с разделением на логические слои чистой архитектуры (это будет необходимо для следующего домашнего задания).
Redux для управления состоянием, hook
реализовывать управление состоянием по паттерну redux: store, state, action, reducer;
организовывать побочные эффекты через middleware (thunk/epics) с обработкой ошибок и ретраев;
интегрировать redux в ui (storeprovider/storeconnector) и минимизировать перестроения;
применять hooks (flutter_hooks, базовые use*) для локального состояния и работы с жизненным циклом виджета;
Архитектура MWWM и Bloc
реализовывать бизнес-логику во bloc/cubit с однонаправленным потоком данных и предсказуемыми состояниями;
интегрировать состояние в ui через blocprovider/blocbuilder/bloclistener/blocselector с минимальными перестроениями;
обрабатывать побочные эффекты, ошибки и конкуренцию событий (debounce/switchmap, transformeevents, bloc_concurrency);
организовывать тестирование блоков/кубитов и наблюдаемость (логирование переходов, blocobserver).
Архитектура MobX
управлять состоянием через MobX: observable, action, computed, сторы как единицы логики;
использовать реакции (autorun, reaction, when) и контролировать их жизненный цикл;
интегрировать MobX в UI через Observer, добиваясь точечных перестроений;
организовывать кодогенерацию (build_runner) и тестирование сторов.
ДЗ
Flutter. State management. Внедряем один из ранее рассмотренных механизмов управления состоянием приложения.
План работы:
1. Выбрать понравившийся state management подход из списка https://docs.flutter.dev/development/data-and-backend/state-mgmt/options и обосновать свой выбор комментарием к ДЗ (не используем GetX ни в кое случае)
2. Внести изменения в код приложения, выделив логику для получения состояния, используя один из ранее рассмотренных подходов к state management, заменить им StatefulWidget.
3. Внести изменения в экран рецепта для управления состоянием isFavourite текущей модели рецепта.
4. Отметку избранного рецепта необходимо показывать и на экране списка рецептов.
5. Добавить сохранение получаемых данных с сервера или локального хранилища (Hive) в выбранный state менеджер.
Модель навигации как управление состоянием. Navigator 2.0
проектировать навигацию как часть состояния приложения (единый источник истины, восстановление стека);
реализовывать вложенные графы: табы с собственными стеками, модальные экраны и диалоги;
настраивать deeplink/url-навигацию (в т.ч. для web), обрабатывать системную «назад»;
синхронизировать навигацию с менеджментом состояния (provider/riverpod/bloc) и правилами доступа (route-guards);
ДЗ
Реализация навигации в приложении на основе состояния.
План работы:
1. Перевести навигацию приложения на использование Navigator 2.0 (Router), можно использовать кодогенерацию (autoroute)
2. Добавить виджет регистрации-аутентификации и соответствующие обращения к API (работает только при наличии сети Интернет, при отсутствии подключения нужно выдавать ошибку)
3. Реализовать вкладку избранных рецептов и присоединить управление состоянием через кнопку ""избранное""
4. Сделать верстку страницы профиля (по информации из логина)
5. Проверить корректность обновления адреса в браузере при использовании Web-версии приложения
Flutter Engine и взаимодействие с платформой.
В модуле рассматривается архитектура движка Flutter, способы вызова методов и обмена сообщениями с нативным кодом, а также общие подходы к доработке движка и сборке под разные аппаратные платформы.
Взаимодействие с платформенным кодом (platform channels, Pigeon, native assets)
проектировать контракты обмена между flutter и нативной платформой (hostapi/flutterapi) и генерировать код через pigeon;
использовать methodchannel/eventchannel/basicmessagechannel и выбирать подходящий канал под задачу;
интегрировать нативные зависимости и ресурсы (native assets), учитывать потоки/жизненный цикл и не блокировать ui;
обрабатывать ошибки/исключения и типобезопасно сериализовать данные между платформами;
Использование нативных Views из Android / iOS, обработка системных событий
встраивать нативные компоненты в flutter-дерево (androidview/uikitview/htmlelementview) и управлять их жизненным циклом;
обрабатывать системные события: applifecyclestate, системная «назад», разрешения, deeplink/url;
согласовывать ввод/фокус/клавиатуру и доступность между нативным view и flutter-ui;
обеспечивать производительность: правильная композиция слоёв, отсутствие лишних перерисовок и блокировок ui-потока.
Устройство Flutter Engine, Add-to-App
понимать слои Flutter (Framework ↔ Engine ↔ Platform) и жизненный цикл приложения;
разобрать Binding’и (Widgets/Rendering/Services) и роль изолятов, кадра и vsync;
понять модели встраивания (Add-to-App): когда и как подключать Flutter к нативному приложению;
учитывать производительность и память при запуске/подогреве движка, многодвижковых сценариях.
ДЗ
Взаимодействие с нативной платформой. Получение информации от внешнего устройства через bluetooth.
План работы:
1. Запросить информацию о доступных Bluetooth Low Energy через плагин (для разработки можно использовать материалы статьи https://punchthrough.com/android-ble-guide/)
2. Отобразить список доступных устройств на странице профиля
Flutter Embedder, запуск приложения на произвольном оборудовании
понимать роль embedder и минимальный контракт платформы (окно/поверхность, ввод, таймеры, изоляты);
настраивать рендер-бэкенд (opengl/metal/vulkan) и пайплайн запуска на нестандартной платформе;
интегрировать системные сервисы (ввод, окно, файлы/ассеты, шрифты) и обмен данными с приложением;
диагностировать производительность/стабильность и управлять ресурсами на уровне платформы.
Консультация по ДЗ + практика
разобрать вопросы по add-to-app, каналам (pigeon), platform views и embedder;
отработать проектирование контрактов обмена (hostapi/flutterapi) и обработку системных событий;
улучшить производительность: снизить блокировки ui-потока и лишние перерисовки;
зафиксировать чек-лист качества интеграций и план доработок по проекту.
Тестирование и публикация
В модуле будут рассмотрены вопросы создания автоматических тестов для алгоритмов, виджетов и приложения в целом, подготовки библиотек и приложений к публикации на pub.dev и в магазинах приложений Google Play Store и Apple Store, особенности публикации для Huawei.
Unit-тестирование и виджет-тесты
писать модульные тесты для бизнес-логики и утилит;
разрабатывать виджет-тесты с изоляцией зависимостей и контролем buildcontext;
настраивать golden-тесты для визуальной регрессии и стабильных снапшотов;
организовывать тестовые двойники (mocks/fakes) и фикстуры данных.
Интеграционные тесты
писать интеграционные тесты end-to-end на integration_test;
запускать тесты на эмуляторах/реальных устройствах и собирать артефакты прогона;
настраивать ci/cd для сборки, анализа, тестов и публикации артефактов;
управлять нестабильными тестами (flaky), параллелизацией и временем выполнения;
ДЗ
Разработка автоматических тестов для приложения (тестирование логики и виджетов).
План работы:
1. Подготовить юнит-тест для менеджера управления списком рецептов (проверить добавление/получение рецепта), использовать mockito/mocktail для подмены слоя доступа к данным
2. Создать тестирование виджетов для страницы информации о рецепте (переключение ""избранное"", шагов приготовления рецепта, отображение всех виджетов)
3. Сделать golden-тест для карточки рецепта (виджет, который используется в списке рецептов)
4. Сделать интеграционный тест (просмотр списка рецептов, переход в рецепт, проверить что открывается страница с информацией о рецепте, а также возможность использование кнопки ""избранное"")
Создание собственных компонентов, публикация на pub.dev
структурировать пакет: lib/src, публичный api, примеры, документация (dartdoc);
обеспечить качество пакета: линты, тесты, совместимость версий, score и поддержка;
применять семантическое версионирование и управлять зависимостями;
публиковать пакет на pub.dev и настраивать выпуск/поддержку в ci.
Сбор информации о функционировании приложения, публикация в магазины
интегрировать сбор ошибок и крашей (crashlytics/sentry) и настраивать алёрты;
выполнять символикацию релизных сборок (--split-debug-info, obfuscation) и связывать краши с версиями;
готовить релиз: подпись, версии/билд-номера, приватность/разрешения, staged-rollout;
публиковать в app store/google play и мониторить качество после релиза.
ДЗ
Подготовка приложения к публикации в магазине.
План работы:
1. Определить необходимые метаданные в pubspec.yaml (название приложения, версия)
2. Установить ключи публикации (можно использовать отладочные ключи при отсутствии учетной записи разработчика) в build.gradle
3. Выполнить сборку артефакта aab и добавить его к проекту
Курсовой проект
Завершающий модуль с самостоятельной разработкой функционального приложения с поддержкой сетевого взаимодействия, изолятов, платформенного кода, разметки страниц с использованием анимации и навигации.
Консультация по проектам и домашним заданиям
разобрать вопросы по архитектуре, состоянию, интеграциям и перформансу;
уточнить объём проекта, приоритеты фич и критерии готовности (mvp → релиз);
провести ревью кода/макетов и составить чек-лист качества и рисков;
зафиксировать план доработок и метрики, по которым будем измерять прогресс.
Защита проектных работ
представить решение: сценарии, архитектуру, ключевые технические решения;
продемонстрировать стабильность и производительность (метрики/трейсы/тесты);
ответить на вопросы комиссии и получить рекомендации по улучшениям;
зафиксировать следующую итерацию развития проекта.
Подведение итогов курса
подвести итоги по компетенциям и определить зоны роста для следующего уровня;
разобрать пути трудоустройства/развития (позиции, требования, портфолио);
зафиксировать план дальнейшей практики: задачи, open source, публикации/релизы;
обсудить процедуры получения сертификата и взаимодействие после курса.