Flutter & Dart | Мобильный трудоголик
189 subscribers
19 photos
1 video
51 links
Пишу простым языком про разработку на Flutter & Dart (iOS, Android, macOS, Windows) и мобильную разработку в целом.
Обо мне: https://xn--r1a.website/hardworkerFlutter/2
Чат: @flutterDevChat
Другие мои каналы: @hardworkerIT и @itDenisov
Download Telegram
🏋️ Установка APK на Android усложняется: придется ждать сутки

С августа 2026 года установка APK-файлов от неизвестных разработчиков на Android станет сложнее. Google вводит продвинутый процесс, который должен защитить пользователей от мошенников, но заодно превращает установку любого приложения не из Google Play в квест.

Это касается не только нативных разработчиков, но и разработчиков на Flutter, которые собирают приложения под Android и которые распространяют свои приложения в обход Google Play (например через сайты, соц. сети или телеграм). Это означает, что привычный способ «включил неизвестные источники -> установил» больше не сработает. Вместо этого - сутки ожидания, биометрия и подтверждение, что вас никто не принуждает.


Что изменится:

Раньше достаточно было включить разрешение на установку из неизвестных источников и можно было ставить любой APK. Теперь нужно будет пройти целую процедуру:

🔵Включить режим разработчика.

🔵Подтвердить, что вас никто не принуждает.

🔵Перезагрузить телефон.

🔵Подождать сутки.

🔵Пройти биометрическую проверку.

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


Почему ввели данный процесс:

Google объясняет это борьбой с мошенниками. По статистике Global Anti-Scam Alliance, 57% взрослых сталкивались с мошенничеством за последний год, а ущерб составил 442 миллиарда долларов. Мошенники часто давят на жертв по телефону, заставляя прямо сейчас отключить защиту и установить вредоносное приложение. Принудительная пауза в сутки должна сломать эту схему.

Для тех, кто просто хочет установить приложение от независимого разработчика, это кажется излишним и выглядит как наказание.


🔗 Читать подробнее


💡 Вывод:

Android теряет одну из главных своих особенностей - свободу установки любого приложения без ограничений. Теперь это будет возможно только после процедуры с суточным ожиданием. Google говорит о безопасности и это действительно важная тема. Для нативных разработчиков и Flutter-разработчиков, которые тестируют сборки на реальных устройствах, раздают бета-версии клиентам через телеграм или просто устанавливают собственные APK в процессе разработки, это ощущается как шаг назад. В погоне за защитой от мошенников страдают в том числе разработчики, которым нужна возможность быстро ставить приложения не из магазина.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👀4🙏2👍1🗿1
👣 Когда в Dart нужен covariant и как он работает

В Dart есть ключевое слово covariant, о котором многие слышали, но используют редко. А зря, оно решает конкретную проблему с переопределением методов в наследниках, когда нужно уточнить тип параметра. Разбираемся, как это работает и в каких случаях пригождается.


В чем суть проблемы:

Представьте, что у вас есть базовый класс Employee с методом process, который принимает любой тип документа (Document). Вы создаете наследника Manager, который по логике должен работать только с отчетами (Report), а не с любыми документами.

По умолчанию Dart этого не позволит. Метод в наследнике должен принимать тот же тип, что и в родителе - Document. Если вы попытаетесь сузить тип до Report, компилятор выдаст ошибку.



class Employee {
void process(Document doc) {}
}

class Manager extends Employee {
@override
void process(Report doc) {} // ошибка переопределения
}



Что делает covariant:

Ключевое слово covariant говорит компилятору: «Этот параметр может быть сужен в наследниках». Добавляем его в базовый класс и все работает:


class Employee {
void process(covariant Document doc) {}
}

class Manager extends Employee {
@override
void process(Report doc) {} // теперь можно
}


Теперь метод process у Manager принимает только Report. Попытка передать Invoice вызовет ошибку типов.


Когда это полезно:

Ситуации, когда нужно уточнить тип параметра в наследнике, возникают не так часто, но бывают. Например:

🔵В абстрактном классе описывается обработчик событий, а в конкретной реализации нужно указать более точный тип события.

🔵В фабриках и билдерах, где базовый метод принимает общий тип, а наследники работают с конкретными объектами.

Без covariant пришлось бы делать приведение типов внутри метода или проверять тип вручную. С ним код становится чище и типобезопаснее.


🔗 Читать подробнее


💡 Вывод:

covariant - инструмент на случай, когда нужно уточнить тип параметра в наследнике, не ломая контракт базового класса. В повседневной разработке он нужен нечасто, но знание о нем помогает писать более точный и типобезопасный код. Если вы когда-нибудь ловили себя на мысли «хотелось бы указать в наследнике более конкретный тип», то covariant - это именно то, что нужно.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥21
👣 Что важно знать о BuildContext в Flutter

Для многих начинающих разработчиков BuildContext остается чем-то вроде магической переменной - появляется из ниоткуда, что-то делает, но как именно непонятно. На самом деле это интерфейс к элементу в дереве виджетов. Когда вы пишете виджет, вы описываете конфигурацию. А context - это ваш пропуск к тому, что реально существует в памяти.


Как на самом деле работает поиск:

Когда вы вызываете Theme.of(context), Flutter начинает подниматься вверх по дереву от текущего контекста, пока не найдет ближайшего предка нужного типа. Если у вас вложенные темы, context определяет, какую из них вы получите.

Отсюда и берутся проблемы: Navigator.of(context) иногда не работает, потому что контекст находится выше того навигатора, который вы пытаетесь использовать. Или Scaffold.of(context) не видит Scaffold, потому что context создан раньше.


Где чаще всего спотыкаются:

🔵initState - запретная зона. Нельзя использовать context напрямую в initState. Если нужно что-то показать при открытии экрана, приходится использовать addPostFrameCallback. Иначе приложение упадет.

🔵Асинхронные операции - ловушка. Вы сделали запрос, ждали ответа, а пользователь уже закрыл экран. Если попробовать использовать старый context будет краш. Поэтому после каждого await нужно проверять if (!context.mounted) return;

🔵Диалоги - отдельная история. Чтобы закрыть диалог изнутри, нужно использовать контекст, который приходит в builder, а не тот, что был снаружи. Иначе навигатор не поймет, что именно закрывать.


🔗 Читать подробнее


💡 Вывод:

BuildContext - это не магия, а просто доступ к элементу в дереве. Понимание того, как Flutter ищет предков, как работает mounted и когда контекст можно использовать - это база, без которой в больших проектах не обойтись. Ошибки с контекстом - одни из самых частых у новичков. И они решаются не гаданием, а пониманием того, что на самом деле происходит под капотом.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32🔥1
👣 DataTable и Table: работа с таблицами во Flutter

В повседневной работе мы привыкли к Column, Row, ListView. Они закрывают большинство задач по построению интерфейсов. Но иногда требуется настоящая таблица: строки, столбцы, сортировка, постраничная навигация. И здесь у Flutter есть несколько специализированных инструментов, о которых многие забывают.


DataTable - для небольших объемов:

Если у вас предсказуемый, небольшой набор данных - идеальный вариант. DataTable строится на основе DataRow и DataCell, все объявляется декларативно. Подходит для экранов настроек, административных панелей, любых мест, где таблица не превышает десятка строк. Сортировка подключается через onSort, постраничное отображение контента - через PaginatedDataTable, которая оборачивает обычную DataTable и добавляет навигацию.


Table - полный контроль:

Если нужно управлять каждой ячейкой, задавать разную ширину колонок, рисовать границы, вставлять сложные виджеты - используйте Table. Здесь вы сами определяете каждую строку как TableRow, а внутри - список ячеек с любыми виджетами. Можно задавать ширину колонок: фиксированную (FixedColumnWidth), пропорциональную (FlexColumnWidth) или по содержимому (IntrinsicColumnWidth).


Что важно знать:

🔵IntrinsicColumnWidth - заставляет Flutter делать два прохода: сначала измерить все, потом отрисовать. На сотнях строк это может начать тормозить.

🔵Адаптивность - на узких экранах таблица может стать нечитаемой. Лучше либо предусмотреть горизонтальный скролл, либо на мобильных устройствах заменять таблицу на другой тип компоновки.

🔵Динамическая высота строк - если содержимое ячеек часто меняется, Table может работать неоптимально. Здесь иногда проще собрать свой вариант через ListView + Row.


🔗 Читать подробнее


💡 Вывод:

DataTable и Table - не самые популярные виджеты во Flutter, но в своих нишах они незаменимы. DataTable удобен для небольших, четко структурированных данных с сортировкой и пагинацией. Table - для кастомных макетов, где нужно полное управление шириной и содержимым ячеек. Если объемы большие или содержимое часто меняется, стоит присмотреться к другим подходам.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62🔥1
👣 Как Dart и Flutter смотрят на ИИ в 2026 году

Команда Flutter опубликовала размышления о том, как искусственный интеллект влияет на развитие экосистемы. Это не дорожная карта, а скорее честный взгляд на текущую ситуацию. Потому что в 2026 году невозможно делать инструменты для разработки, не обращая внимания на ИИ.


Цифры, которые объясняют все:

Согласно опросам, 84% разработчиков в целом используют ИИ-инструменты в своей работе. Среди Flutter-разработчиков этот показатель чуть ниже - 79%, но все равно впечатляет. Однако есть проблема: 46% не доверяют точности ИИ при решении критических задач. Это тратит лишнее время на проверку сгенерированного кода.


Главные принципы:

Команда декларирует несколько ключевых правил, которым следует при развитии ИИ-направления:

🔵Человек прежде всего. Dart остается языком, который легко читать и поддерживать человеку, даже если код написан ИИ. Это важно, потому что ИИ-сгенерированный код не должен превращаться в нечитаемую кашу.

🔵Добавлять, а не заменять. ИИ-инструменты должны дополнять опыт разработки, а не вытеснять разработчика. Каждый сам решает, использовать ИИ или нет и в каком объеме. При этом документация и базовые инструменты остаются источником истины.

🔵Открытые стандарты и агентная нейтральность. Flutter должен хорошо работать с любым агентом, не только с Gemini. Для этого используются открытые протоколы вроде MCP. Например, недавно добавили MCP-инструмент для поддержки горячей перезагрузки при разработке с ИИ.

🔵Доверие через качество. Главная проблема ИИ-генерации - затраты времени на проверку. Команда работает над тем, чтобы сгенерированный код был точным, идиоматичным и соответствовал стандартам проекта. Для этого сотрудничают с Google Deepmind и Antigravity по оценке моделей.


🔗 Читать подробнее


💡 Вывод:

Команда Flutter не пытается предсказать будущее ИИ, а экспериментирует на виду, честно говоря о своих намерениях. ИИ не станет обязательной частью экосистемы, но для тех, кто хочет его использовать, инструменты будут. И при этом никто не заставляет отказываться от традиционной разработки - это тоже полностью валидный путь. Главное - чтобы у разработчика был выбор.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1🙏1👀1
👣 Как удалить все неиспользуемые импорты во Flutter-проекте

В каждом проекте рано или поздно появляются серые, поблекшие импорты. Они висят, ни на что не влияют, но глаза мозолят. Ревьюеры тратят время на проверку, нужны ли они вообще. А кодовая база обрастает балластом, который никто не замечает, но всем мешает.


Одна команда, которая все решает:

В корне проекта достаточно выполнить:


dart pub get && dart fix --apply


Анализатор Dart пробежится по всем файлам, найдет неиспользуемые импорты и удалит их. Без лишних вопросов, без ручного перебора каждого файла.

Если хочется сначала посмотреть, что именно будет удалено, можно выполнить dart fix --dry-run. Покажет список изменений, но ничего не тронет.


Почему об этом вообще стоит думать:

Неиспользуемые импорты не ломают код, но они делают его грязным. Ревьюеры тратят время на проверку того, что на самом деле не используется. Линтеры и форматтеры работают хуже, когда списки импортов захламлены. А сам проект со временем становится тяжелее и менее понятным.

dart fix решает эту проблему мгновенно. Инструмент официальный, встроенный в экосистему Dart, так что никаких сторонних зависимостей тащить не нужно.


Что важно помнить:

Перед массовой чисткой лучше сделать коммит - мало ли что. Сгенерированные файлы (.g.dart) dart fix трогать не должен, они все равно перезапишутся при следующей сборке. И всегда после чистки стоит прогнать dart analyze && flutter test, чтобы убедиться, что ничего не сломалось.


🔗 Читать подробнее


💡 Вывод:

dart fix --apply - это не магия, а просто правильный инструмент. Он не делает код быстрее и не добавляет новых фич. Зато он убирает мусор, который отвлекает, запутывает и создает иллюзию сложности. Если в вашем проекте есть неиспользуемые импорты - команда решит проблему за секунду. Если их нет - вы либо уже все почистили, либо просто не замечаете.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41
👣 Material и Cupertino больше не часть SDK Flutter

Команда Flutter объявила о заморозке изменений в библиотеках Material и Cupertino внутри основного SDK. Это первый шаг к самому масштабному архитектурному изменению в истории фреймворка - полному отделению дизайн-систем от ядра. Теперь Material и Cupertino станут обычными пакетами на pub.dev.


Какую проблему решает это изменение:

Сейчас Material и Cupertino жестко привязаны к Flutter и обновляются только с релизами SDK. Это создает несколько проблем:

🔵Зависимость от цикла релизов. Нашли баг в Material? Ждите три месяца, пока выйдет новый релиз Flutter. Нужна свежая версия Material 3? Обновляйте весь SDK, даже если вам это не нужно.

🔵Невозможность кастомизации. Сложно сделать свою дизайн-систему, чтобы из нее не торчали уши Material или Cupertino.

🔵Сложности для энтузиастов. Чтобы поправить баг в кнопке Material, нужно разбираться с локальной сборкой Flutter.

После разделения библиотеки Material и Cupertino будут обычными пакетами на pub.dev со своим версионированием и циклом обновлений.


Что будет происходить дальше:

С 7 апреля все изменения в Material и Cupertino внутри Flutter заморожены. Дальнейшая разработка продолжится в репозитории flutter/packages, где появятся новые пакеты - material_ui и cupertino_ui. После выхода стабильного релиза Flutter 3.44 новые пакеты станут доступны, и разработчикам нужно будет постепенно переходить на них.

Старые библиотеки Material и Cupertino в SDK будут объявлены устаревшими в следующем релизе после 3.44 и удалены спустя какое-то время.


🔗 Читать подробнее


💡 Вывод:

Flutter перестает быть фреймворком со встроенными Material и Cupertino и становится платформой, где дизайн-системы живут своей жизнью. Это не просто техническое изменение, а смена подхода: ядро SDK становится легче и стабильнее, а дизайн-системы - независимыми, с собственными циклами обновлений. Разработчики получают свободу выбора: можно использовать Material, Cupertino или свою собственную дизайн-систему. Баги теперь будут фикситься быстрее - не нужно ждать квартального релиза Flutter.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2👀1
📱 Отключаем запрос о соответствии экспортным требованиям в TestFlight

Загружая новую сборку iOS-приложения, всегда приходится заходить в App Store Connect для нажатия на «Нет» в окне «Информация о соответствии экспортным требованиям».

Если ваше приложение не использует шифрование, то можно очень просто избавиться от ручного подтверждения при каждой загрузке сборки в TestFlight.

Для этого необходимо открыть файл Info.plist в папке /ios/Runner и добавить следующие строки:

<key>ITSAppUsesNonExemptEncryption</key>
<false/>


Что это дает:

🔵Больше не нужно вручную отвечать «Нет» в App Store Connect.

🔵Сборки сразу становятся доступными для тестирования в TestFlight после обработки.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3🔥1
👣 Оптимизация производительности приложений на Flutter

Производительность Flutter-приложения напрямую зависит от того, как написан код. Лишние перестройки UI, тяжелые операции в основном потоке, неправильная работа со списками и изображениями - все это ведет к фризам, падению FPS и раздраженным пользователям. В этом посте обсудим наиболее распространенные ошибки, которые превращают быстрый фреймворк в тормознутое приложение.


Лишние перестройки UI:

Самая частая проблема - setState, который пересобирает все дерево виджетов целиком. Даже если изменился один текст, Flutter заново вызывает build() для всех дочерних элементов. В маленьком проекте это незаметно. Когда же внутри есть списки, картинки и сложные layout'ы, каждое нажатие кнопки начинает тормозить интерфейс. Решение - использовать ValueListenableBuilderStreamBuilder или аналоги, которые обновляют только нужную часть.


Отсутствие const:

Многие забывают про const. Без него каждый rebuild создает новые объекты виджетов, даже если они идентичны предыдущим. Это увеличивает нагрузку на сборщик мусора и процессор. В больших списках или сложных UI это дает заметный прирост производительности - достаточно просто добавить const там, где это возможно.


Логика внутри build():

build() может вызываться десятки раз в секунду - при анимациях, скролле, обновлениях. Если внутри выполнять сортировку, фильтрацию или парсинг, это напрямую убивает производительность. Даже простая операция sort() на среднем списке может занимать миллисекунды, а для 60 FPS на каждый кадр есть всего 16 мс. Вся логика должна быть вынесена в initState или бизнес-слой.


ListView без builder:

Когда вы используете ListView(children: [...]), Flutter создает все элементы списка сразу, даже если пользователь видит только первые 5–10. При 100+ элементах это приводит к лишним аллокациям, перегрузке памяти и долгому первому рендеру. ListView.builder создает элементы лениво - только те, что видны на экране. Это значительно снижает нагрузку.


Отсутствие ключей:

Без key Flutter не может корректно сопоставить старые и новые элементы при обновлении списка. В результате он пересоздает виджеты вместо их обновления, что приводит к лишним rebuildам и визуальным багам - например, прыгающим элементам. ValueKey или ObjectKey решают эту проблему.


🔗 Читать подробнее


💡 Вывод:

Большинство проблем с производительностью возникают не из-за сложности задачи, а из-за мелких решений, которые легко упустить в процессе разработки. Лишний rebuild, тяжелая операция в основном потоке, список без builder - каждое из этих решений кажется безобидным, пока приложение не начинает тормозить. Хорошая новость в том, что большинство описанных проблем решаются относительно просто. Главное - не откладывать это на потом.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥21🙏1
👣 Убираем хардкод и лишние перерисовки с помощью стандартных виджетов

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


LayoutBuilder - адаптивный интерфейс без хардкода:

Проблема: нужно показывать разную верстку в зависимости от ширины экрана. Многие начинают писать проверки через MediaQuery или пытаются угадать размеры устройства. Но это неправильно - важно не само устройство, а реальное место, которое виджет занимает на экране.

LayoutBuilder дает доступ к ограничениям родителя прямо во время построения. Вы можете посмотреть максимальную ширину и решить, показывать горизонтальное меню или вертикальное, две колонки или одну. Все адаптируется под текущий контейнер, а не под экран в целом.

LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > 600) {
return Row(children: [sidebar, content]);
}
return Column(children: [sidebar, content]);
},
)



AnimatedSwitcher - плавные переходы между виджетами:

Смена одного виджета на другой обычно выглядит резко. Текст изменился - моргнул, иконка сменилась - тоже моргнула. AnimatedSwitcher добавляет анимацию при замене дочернего элемента. Старый виджет плавно исчезает, новый - появляется. Вы можете настроить тип перехода: затухание, сдвиг, масштаб.

Важный момент: анимация сработает только если у виджетов разные key. Иначе AnimatedSwitcher решит, что ничего не изменилось.

AnimatedSwitcher(
duration: Duration(milliseconds: 300),
child: Text(counter.toString(), key: ValueKey(counter)),
)



🔗 Читать подробнее


💡 Вывод:

Все эти виджеты решают повседневные задачи: адаптивную верстку, плавную смену контента, простые анимации и оптимизацию перерисовок. Они есть в стандартной библиотеке, не требуют подключения сторонних пакетов и при этом заметно упрощают код. Если вы до сих пор писали свои велосипеды для таких случаев - попробуйте заменить их на встроенные решения.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍2🙏1
👣 Flutter: выносим бизнес-логику из BLoC в use-cases

При разработке Flutter-приложений паттерн BLoC часто становится всемогущим объектом, впитывающим всю бизнес-логику. Внутри хендлеров оказываются и запросы к сервисам, и валидация и эмиттеры состояния. Проект разрастается, файлы раздуваются, тестирование становится невозможным. Сегодня обсудим как можно вынести бизнес-логику в отдельные классы - use-cases.


Как это работает:

Вместо того чтобы вызывать сервисы прямо внутри хендлеров BLoC, вся логика конкретного сценария (например загрузки товаров) выносится в отдельный класс. Use-case зависит от абстракций репозиториев и сервисов, но ничего не знает про UI. Он вызывает нужные зависимости, обрабатывает ошибки, выполняет side-эффекты и только после этого отправляет событие в BLoC. Сам BLoC превращается в тонкую прослойку: принимает события, обновляет состояние и больше ничего не делает.

Как это работает на практике:

Огромный BLoC-файл, отвечающий за получение данных, кэширование, фильтрацию и обновление UI, превращается в узкое место проекта. Конструктор забит зависимостями, тестирование почти невозможно. После рефакторинга BLoC сокращается до 20-30 строк, не зависит от сервисов и становится просто набором функций для обновления состояния. Все пользовательские сценарии выносятся в отдельные use-cases.

В результате время разработки нового функционала сокращается, количество багов снижается, тесты становятся надежнее.


Почему это работает:

Use-case оркестрирует несколько сервисов и репозиториев, объединяет данные, обрабатывает ошибки, логирует и только после этого отправляет событие в BLoC. BLoC остается только стейт-менеджером и не выполняет ничего, кроме преобразования событий в состояние. Такой подход соответствует принципам чистой архитектуры: доменный слой не зависит от реализации, что повышает гибкость и тестируемость.


🔗 Читать подробнее


💡 Вывод:

Разделение бизнес-логики и UI - необходимость для масштабируемых приложений. Use-cases помогают структурировать код, упрощают тестирование и делают BLoC максимально простым. Этот подход не привязан к BLoC и может использоваться с любым другим стейт-менеджером.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥51👍1
👣 Команда Flutter перевела свои сайты на Jaspr - фреймворк на Dart

Команда Flutter объявила о миграции трех основных своих сайтов (dart.devflutter.dev и docs.flutter.dev) на Jaspr - open-source фреймворк для создания веб-сайтов на Dart. Раньше сайты были собраны из разных технологий: документация работала на Eleventy (Node.js), а основной сайт - на Wagtail (Python + Django). Теперь все на Dart.


Почему они решили это сделать:

Старая архитектура была фрагментированной. Чтобы вносить правки или поддерживать сайты, нужно было знать Node.js, Python и Dart одновременно. Это создавало барьер для контрибьюторов и усложняло поддержку. Кроме того, добавление интерактивных элементов (например, викторин в туториалах) требовало сложных, разовых решений.


Что изменилось:

Теперь все три сайта используют единый стек на Dart. Основные изменения:

🔵Единая тулчейн. Все управляется через dart pub, dart format, dart analyze, dart test. Не нужно переключаться между разными экосистемами.

🔵Порог входа снизился. Если вы знаете Dart, вы можете вносить вклад в документацию Flutter. Никакого дополнительного обучения.

🔵Частичная гидратация. Jaspr умеет рендерить страницы как статический HTML, а потом подключать клиентскую логику только для тех компонентов, которым это нужно. Это дает быструю загрузку и хорошее SEO.

🔵Контент остался в Markdown. Рабочие процессы авторов почти не изменились. Jaspr Content поддерживает Markdown из коробки.


Почему так лучше:

🔵Flutter-разработчики чувствуют себя как дома. Компоненты Jaspr напоминают Flutter-виджеты, синтаксис похож.

🔵Современный Dart. Используются последние фичи языка: точечные шорткаты, null-aware элементы, свежие возможности JS-интеропа.

🔵Легко добавлять интерактив. Встроенная поддержка частичной гидратации позволяет без боли внедрять динамические элементы на статический сайт.

🔵Плагин анализатора. Jaspr предоставляет линтер и автодополнения прямо в IDE, как у Flutter.


🔗 Читать подробнее


💡 Вывод:

Миграция на Jaspr - пример того, как сообщество и официальная команда совместно улучшают экосистему. Единый стек на Dart упрощает поддержку, снижает порог входа для контрибьюторов и открывает возможности для более интерактивной документации. Если вы когда-нибудь хотели попробовать веб-разработку на Dart - теперь есть отличный повод.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42
👣 Команда Flutter отправляется в тур по конференциям: список ивентов на 2026

Команда объявила о своем участии в десятках конференций по всему миру в 2026 году. Цель - не просто показать доклады, а лично пообщаться с разработчиками, увидеть демо вживую и собрать обратную связь. Это хорошая возможность для всех, кто давно хотел задать вопрос команде или поделиться своим мнением.


Где и когда:

В апреле стартует Google Cloud Next в Лас-Вегасе. В мае - Flutterconf в Испании, Google I/O в Саннивейле и Flutter Flow Developers Conference в Сан-Франциско. Летом команда будет в Праге, Варшаве, Берлине, Бангалоре и Орландо. Осенью - в Стокгольме, Канкуне, Берлине, Токио и других городах. Полный список обновляется на странице событий Flutter.dev.


Если вы не можете приехать - не проблема:

Многие из перечисленных конференций транслируются онлайн, а их записи потом выкладывают в открытый доступ. Это означает, что вы можете посмотреть доклады команды Flutter, не выходя из дома - прямо во время трансляции или в удобное время после. Так что даже если вашего города нет в списке, вы все равно сможете узнать обо всех новинках и важных новостях.


Почему это важно:

Flutter - это огромное сообщество. Команда говорит, что самые яркие моменты ее карьеры связаны с живым общением на ивентах. Они хотят слышать не только через баг-репорты и пул-реквесты, но и лично. Это важно для развития фреймворка.

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


🔗 Читать подробнее


💡 Вывод:

Если вы давно хотели встретиться с командой Flutter, задать вопрос или просто посмотреть на живые демо - теперь у вас есть такая возможность. Список конференций на 2026 год уже опубликован, и он довольно обширный. А если не можете приехать - ищите онлайн-трансляции и записи. Следите за обновлениями на сайте Flutter.dev.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🗿1
👣 Два года спустя: как увольнения повлияли на Flutter

Всем привет! Сегодня хочу разобрать интересную статью про судьбу Flutter после увольнений в Google. В апреле 2024 года Google уволил инженеров из команд Flutter, Dart и Python - за несколько недель до Google I/O, где традиционно анонсировали светлое будущее. Тогда было много паники и постов «Flutter умер». Прошло два года. Flutter не умер. Но и не остался прежним. Пора без истерик разобраться, что на самом деле изменилось.


Что тогда произошло:

Увольнения затронули в основном DevOps и инфраструктуру, а не разработчиков самого фреймворка. План развития продукта не изменился. Но сообщество правильно прочитало сигнал: для Google Flutter - больше не стратегический приоритет, а просто поддерживаемый продукт. Разница огромная. Стратегическому приоритету выделяют лучших инженеров, лоббируют внутри компании, вкладывают ресурсы. Поддерживаемому продукту - фиксят критические баги, но новых горизонтов не открывают.


Что случилось потом:

Flutter продолжил выпускать релизы. Impeller стал стабильным. Дорожная карта 2024 года выполнена. BMW, Alibaba и eBay все еще используют Flutter на проде. Опрос Stack Overflow 2024 показал 46% использования среди кроссплатформенных фреймворков - больше, чем у React Native (35%).

Но вот что важно: Тим Снит (многолетний руководитель разработки Flutter, лицо проекта на I/O) ушел в Apple в 2023 году. Брэндон ДеРозье (создатель Impeller) в 2025 году перешел в команду Android XR. Это не увольнения. Это добровольные уходы ключевых людей. И они сигнализируют о том, что даже внутри Google самые талантливые инженеры перестали видеть будущее за Flutter.


Почему я все еще использую Flutter:

Фреймворк работает. Для 90% задач кроссплатформенной разработки - стабильно, быстро, предсказуемо. Сообщество огромное, уже более 50 000 пакетов на pub.dev. Релизы выходят четыре раза в год. С точки зрения инженерной реальности Flutter не стал хуже.

Но соотношение затрат и выгод изменилось. Теперь нужно задавать себе другие вопросы.


🔗 Читать подробнее


💡 Вывод:

Используйте Flutter там, где он подходит. Понимайте свои зависимости и риски. Не принимайте архитектурные решения по звездам на GitHub и по рекомендациям от ИИ. Релевантный показатель один: решает ли фреймворк вашу проблему сегодня и есть ли у него разумный путь поддержки на три года вперед. По этому показателю Flutter проходит проверку. Не на отлично. Не так уверенно, как в 2021 году. Но проходит. Те, кто ожидает немедленного краха, ошибаются. Те, кто утверждает, что все осталось по-прежнему, тоже ошибаются. Правда, как обычно, посередине: Flutter - рабочий инструмент, но теперь его стоит выбирать с открытыми глазами, понимая, что уровень поддержки со стороны Google может и дальше снижаться.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍1👀1
👣 Как создать свое расширение для Dart DevTools

Привет! Наткнулся на статью, где автор подробно рассказывает, как добавить собственную вкладку в Dart DevTools и настроить взаимодействие с запущенным Flutter-приложением. Оказывается, это не так сложно, как кажется.


С чего начать:

Первым делом создается новый пакет под расширение. Официального шаблона нет, поэтому структуру добавляют вручную. В корне пакета создается папка devtools, внутри - build и файл конфигурации config.yaml. В конфиге указываются имя, версия, иконка для вкладки и трекер ошибок:

Файл config.yaml:

name: my_dev_tools_ext
issueTracker: https://...
version: 0.0.1
materialIconCodePoint: '0xe0b1'
requiresConnection: false


Для работы расширения нужен пакет devtools_extensions. Он дает доступ к менеджерам: extensionManager (взаимодействие с DevTools), serviceManager (доступ к VM-сервису) и dtdManager (связь с Dart Tooling Daemon).


Интерфейс и тестирование:

Сами виджеты можно собирать из готовых компонентов пакета devtools_app_shared. Например DevToolsButton уже имеет стиль, подходящий для интерфейса DevTools, а через extensionManager.showNotification можно показывать уведомления.

Для отладки расширения используется симулированная среда:

flutter run -d chrome --dart-define=use_simulated_environment=true


Перед публикацией сборка создается командой build_and_copy, а проверить корректность структуры можно через validate.


Два типа расширений:

🔵Standalone extensions - отдельные пакеты, не привязанные к существующему pub-пакету. Подходят для инструментов, которые могут пригодиться в любом проекте.

🔵Companion extensions - поставляются вместе с существующим pub-пакетом. Когда пользователь подключает такой пакет, расширение автоматически появляется в DevTools. Для этого в корне пакета достаточно добавить папку extension/devtools со сборкой и конфигом.


🔗 Читать подробнее


💡 Вывод:

Расширения DevTools открывают интересные возможности для создания инструментов отладки, визуализации состояния и даже управления приложением в рантайме. Статья дает хороший практический старт: от создания пакета до выполнения произвольного Dart-кода на живом приложении. Если вы когда-нибудь хотели добавить свою вкладку в DevTools - это вполне реально.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32🙏1
👣 Улучшаем локальный поиск на Dart и Flutter

Обычный строковый поиск работает только при точном совпадении. Одна лишняя буква, опечатка или другой падеж и результат пустой. В этой статье автор разбирает, как реализовать локальный поиск, который понимает, что пользователь имел в виду, даже если ввел с ошибкой.


Почему простое вхождение не работает:

Пользователи часто ошибаются. Вместо «Арбатская» пишут «Орбатская», вместо «Петровка» - «Питровка». Простой поиск по вхождению подстроки такие запросы игнорирует. А отправлять каждый запрос на сервер - долго и не всегда возможно.


Что такое расстояние Левенштейна:

Это число, которое показывает, сколько операций нужно, чтобы превратить одну строку в другую. Операции - вставка, удаление, замена символа. Например, «кот» -> «код»: одна замена символа, расстояние = 1. «Австрия» -> «Австралия»: нужно добавить две буквы, расстояние = 2.

Для поиска удобнее использовать нормализованное значение от 0 до 1, где 0 - полное совпадение, 1 - строки разные.


Более точный вариант - расстояние Дамерау‑Левенштейна:

Оно добавляет еще одну операцию - перестановку соседних символов. Это одна из самых частых опечаток: «годки» вместо «годик». Обычное расстояние Левенштейна даст 2, а расстояние Дамерау‑Левенштейна - 1, потому что достаточно переставить буквы.


Как это реализовать во Flutter:

Автор приводит пример поиска по адресам и станциям метро. Алгоритм:

🔵Привести строки к нижнему регистру.

🔵Вычислить расстояние Дамерау‑Левенштейна между поисковым запросом и каждым элементом списка.

🔵Добавить к адресу название метро, если оно есть.

🔵Отсортировать результаты по близости (чем меньше расстояние, тем выше результат).

🔵Отфильтровать только те, где расстояние меньше заданного порога (например, 0.5).


🔗 Читать подробнее


💡 Вывод:

Такой поиск имеет смысл не везде. В идеале - отдать поиск на бэкенд, если он это умеет. Если нет и приходится искать локально, расстояние Дамерау-Левенштейна может спасти ситуацию. Но не ждите чудес: алгоритм требовательный к ресурсам, а порог совпадения придется подбирать вручную.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🔥1
👣 Flutter отказывается от CocoaPods в пользу Swift Package Manager

Начиная с релиза Flutter 3.44, Swift Package Manager (SwiftPM) заменяет CocoaPods как стандартный менеджер зависимостей для iOS и macOS. Это означает, что больше не нужно возиться с установкой Ruby или настройкой CocoaPods, чтобы просто запустить приложение.


Почему CocoaPods уходит:

CocoaPods официально переведен в режим поддержки без активного развития. Его реестр станет доступен только для чтения 2 декабря 2026 года. Существующие сборки продолжат работать, но новые версии пакетов добавляться уже не будут. Flutter переходит на решение, которое официально поддерживает Apple, чтобы приложения продолжали получать обновления зависимостей и имели доступ к экосистеме Swift-пакетов.


Что будет с приложениями:

Flutter CLI автоматизирует переход. При сборке или запуске iOS / macOS приложения CLI сам обновит Xcode-проект для использования SwiftPM. Если приложение использует плагины, которые еще не перешли на SwiftPM, Flutter выдаст предупреждение и временно использует CocoaPods для таких плагинов.

В случае критических проблем можно временно отключить SwiftPM в pubspec.yaml:

flutter:
config:
enable-swift-package-manager: false


Но компания просит сообщать о таких проблемах, чтобы успеть их исправить до полного удаления CocoaPods.


🔗 Читать подробнее


💡 Вывод:

Переход на SwiftPM - неизбежный шаг. CocoaPods устарел, и поддержка его заканчивается. Для разработчиков приложений процесс в основном автоматический. А вот авторам плагинов предстоит работа - иначе их пакеты станут несовместимыми и потеряют позиции на pub.dev. Лучше заняться этим сейчас, а не ждать, когда CocoaPods окончательно отключат.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥21
👣 Agent Skills для Flutter и Dart: готовые инструкции для типовых задач

Команда Flutter представила Agent Skills - специальные инструкции, которые делают ИИ-ассистентов более компетентными в разработке на Flutter и Dart. Это не просто документация, а готовые сценарии для типовых задач: локализация, адаптивная верстка, интеграционные тесты, использование новых возможностей языка.


Зачем это нужно:

ИИ-агенты хороши в общих вопросах, но для профессиональной Flutter-разработки этого мало. Нужно понимать нюансы локализации, правильно применять свежие фичи Dart, настраивать интеграционные тесты. Skills закрывают этот пробел.

Важное отличие от MCP: Model Context Protocol дает агентам инструменты (молоток и гвозди), а Skills учат, как этими инструментами пользоваться (чертеж и навыки строителя). Skills также экономят токены благодаря «прогрессивному раскрытию» - агент подгружает инструкции только тогда, когда они действительно нужны.


От теории к практике:

Ранние эксперименты показали: Skills, которые просто дают документацию, не так полезны. Документация Flutter и так открыта и современные модели неплохо умеют находить нужную информацию. Поэтому команда сделала Skills задаче-ориентированными - они учат агента выполнять конкретные действия.


Что уже доступно:

Примеры Skills из открытых репозиториев:

🔵flutter-add-integration-test - настраивает Flutter Driver и превращает MCP-действия в постоянные интеграционные тесты.

🔵flutter-setup-localization - добавляет поддержку локализации в проект.

🔵flutter-build-responsive-layout - создает адаптивный макет через LayoutBuilder, MediaQuery или Expanded/Flexible.

🔵dart-use-pattern-matching - рефакторит код с использованием pattern matching из Dart.

🔵dart-collect-coverage - собирает покрытие тестами и генерирует LCOV-отчет.


🔗 Читать подробнее


💡 Вывод:

Agent Skills - шаг к тому, чтобы ИИ-ассистенты перестали быть просто умными поисковиками и стали реальными помощниками в конкретных задачах. Пока доступен базовый набор, но команда обещает расширять его вместе с сообществом. Agent Skills не превратят ИИ в сеньора, но избавят от необходимости каждый раз объяснять, как настроить локализацию или собрать покрытие тестами.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥2🙏1
👣 yx_navigation: декларативная навигация во Flutter

Привет! Наткнулся на интересную статью, где разработчики из Яндекса рассказывают, как они создали свой пакет для навигации во Flutter. Проблема знакомая: проект растет, появляются табы, вложенные модули, диплинки, а стандартные решения перестают работать. В итоге они написали свое решение и поделились им со всеми.


В чем суть:

Основная идея yx_navigation в том, что состояние навигации - это не стек, а дерево узлов RouteNode. Каждый узел содержит маршрут, параметры и список дочерних узлов. Все просто: добавил узел - экран появился, убрал - исчез.


Какую проблему решает:

🔵Мутация неактивных ветвей. Ключевая фича. Пользователь во вкладке «Сообщения», а в это время прилетает заказ. Его нужно добавить во вкладку «Заказы», но без переключения на нее. В go_router это невозможно - любой переход переключает вкладку. В yx_navigation можно получить контроллер, привязанный к неактивной ветке, и выполнить push из бизнес-логики.

🔵Управление навигацией без BuildContext. Большинство пакетов требуют context для переходов. Интерактор, обрабатывающий push-уведомление, контекста не имеет. В yx_navigation можно создать менеджер состояния заранее и управлять навигацией откуда угодно.

🔵Изоляция фич. Фича подключается одной строкой. Хост не знает о внутренних маршрутах фичи, фича - о хосте. Команды могут работать независимо.

🔵Совместимость с легаси-кодом. Старый код на Navigator.push(), showDialog() продолжает работать. Compatibility Layer адаптирует вызовы к новой модели.

🔵Дружелюбие к разработчику. Встроенная debug-панель показывает дерево состояния в реальном времени, историю мутаций и сериализованное состояние в URL.


🔗 Читать подробнее


💡 Вывод:

yx_navigation - не очередная обертка над Navigator 2.0, а решение, выросшее из реальных проблем крупного проекта. Пакет подойдет тем, кто уперся в ограничения go_router, кому надоело ждать кодогенерацию в auto_route и кто хочет управлять навигацией без привязки к UI и менять состояние даже в неактивных вкладках.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍1🔥1