TGViewer
Channel Public Channel
DartWay Ru | Flutter & Fullstack Dart

DartWay Ru | Flutter & Fullstack Dart

@dartway_dev_ru

Flutter и fullstack Dart в реальной разработке —
без занудства и ненужных абстракций.

Архитектура, практические приёмы, разборы кода.

Для Flutter-разработчиков, которые хотят увереннее чувствовать себя в реальных проектах

💬 @dartway_dev_ru_community
Subscribers
592
Photos
22
Videos
0
Links
37

Showing posts older than #63 · Back to latest

Older Posts 20 shown
Post #61 531
Ура, нас 400 человек!))
  • ❤ 7
Post #60 600
Часто получаю вопросы в духе:
Почему вы ....., а не ....

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

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

На практике всё немного проще.
Результат определяется в первую очередь умением правильно использовать имеющиеся инструменты.

Я как-то раз видел вакансию солидного уровня, в которой в качестве стейт менеджмента были указаны ValueNotifier. Я подумал: "странные ребята, но наверно так тоже можно".
А сейчас со временем всё больше сам прихожу к тому. В наших проектах всё меньше остается сложных стейтов. И риверпод, который мы используем постепенно уходит на второй план.

Но менять инструменты тоже важно. Важно понимать, когда применение выходит за границы гибкости и становится костылями. И тогда пора искать что-то другое.
  • 👍 4
  • ❤ 2
Post #59 630
Опубликовал dartway_router на pub.dev 🚀

Это обёртка над go_router, которую я последние пару лет использую в реальных проектах.
В какой-то момент стало понятно, что из этого вырос не просто набор хелперов, а осмысленный слой навигации — с явной конфигурацией, гардами и предсказуемым поведением.

В итоге я:
привёл API в порядок
почистил нейминг и зависимости
убрал всё лишнее
зафиксировал стабильную версию 1.0.0

📦 Пакет уже доступен на pub.dev:
👉 https://pub.dev/packages/dartway_router

dartway_router — часть экосистемы DartWay и рассчитан на использование в реальных, растущих Flutter-приложениях.

🔥 Вебинар-презентация

Планирую провести открытый вебинар, где:
разберу идею пакета и философию
покажу, как он устроен изнутри
пройду типовые сценарии использования
отвечу на вопросы и соберу обратную связь

Если:
вы используете go_router,
вам важно, чтобы навигация была явной и предсказуемой,
или вы просто хотите посмотреть на альтернативный архитектурный подход,

— напишите в комментариях «вебинар» или задайте вопрос, который хотелось бы разобрать.
По интересу определю формат и дату.
Dart packages dartway_router | Flutter package Opinionated wrapper around go_router that makes routing explicit, predictable, and scalable for real-world Flutter apps.
  • 🔥 6
  • ❤ 1
Post #58 562
... продолжение предыдущего поста

В итоге пришли к более универсальной команде:
она сама учитывает SAR, “выпрямляет” картинку и заодно подгоняет размер под требования кодека (чётные width/height), чтобы не ловить сюрпризы на разных девайсах.

ffmpeg -i input.mp4 \
-vf "scale='iw*sar':ih, pad='ceil(iw/2)*2':'ceil(ih/2)*2', setsar=1" \
-c:v libx264 -crf 19 -preset fast \
-c:a copy output_fixed.mp4

После этого
video_player работает нормально
эмулятор работает
Web работает
никаких костылей в коде

Побочный бонус — производительность.

Анаморфное видео почти всегда означает лишнюю работу при показе:
плееру приходится постоянно скейлить/растягивать картинку
лишняя нагрузка на GPU (иногда CPU)

С квадратными пикселями (SAR = 1:1):
меньше сюрпризов
меньше преобразований
дешевле отрисовка

Особенно заметно на слабых устройствах или когда видео не одно, а в ленте.

Вывод простой

Flutter не «ломает» видео.

Ломает его наследие прошлого — anamorphic encoding,
которое в кроссплатформенных приложениях почти всегда создаёт больше проблем, чем пользы.
  • ❤ 2
Post #57 533
Почему видео ломается во Flutter
Про anamorphic video, SAR/DAR и странности мобильных плееров

Поймали странную историю с видео во Flutter.

Видео нормально играет в VLC и QuickTime, а в приложении на Flutter — сплющено.
Никаких ошибок, просто выглядит неправильно.

Первое ощущение — где-то накосячили с layout или AspectRatio.
Но дальше оказалось, что проблема вообще не в UI.

Материал подготовил Егор, Flutter-разработчик в нашей команде.
Разбирались с этим кейсом в боевом проекте.

Что за видео такое
Смотрим видео через ffprobe:
resolution: 1080×1080
SAR: 9:16
DAR: 9:16

То есть физически видео квадратное, но каждый пиксель не квадратный.
После применения SAR картинка должна быть вертикальной (9:16).

Такой формат называется anamorphic video.

Небольшое отступление, что это вообще значит.
Anamorphic encoding — это когда реальное разрешение и визуальное разрешение не совпадают.
Идея старая, пришла из телевидения и DVD: хранить меньше пикселей, а растягивать их при воспроизведении.

Раньше это имело смысл. Сейчас — почти всегда источник проблем.

Почему это вообще происходит?

Чаще всего такие видео прилетают либо со старых камер/архивов, либо (что куда актуальнее в 2026) — после кривого экспорта из профессионального софта:
Premiere
DaVinci
Media Encoder

Там легко забыть выставить Square Pixels (1.0) в настройках sequence / render — и в файл улетает SAR ≠ 1:1.

Короче: это такой привет от монтажёров.
Снаружи всё выглядит как обычный MP4, а внутри начинается магия с пикселями.

Почему VLC всё показывает правильно

VLC — это не просто оболочка над системным плеером. Он сам:
парсит видеопоток
читает H.264 VUI
учитывает SAR/DAR
сам решает, как рисовать кадр

То есть VLC корректирует геометрию изображения ещё до рендера.

Что происходит во Flutter

В стандартном стеке всё выглядит примерно так:

video_player / chewie / better_player
→ ExoPlayer
→ MediaCodec

Flutter получает от плеера только одно — width и height.
Никакого SAR, никакого DAR.

Для Flutter это просто видео 1080×1080.

Где именно всё ломается
MediaCodec про SAR знает и применяет его внутри декодера
ExoPlayer считает это внутренней деталью и не отдаёт наружу
Flutter Video API вообще не имеет понятия, что пиксели могут быть неквадратными
В итоге layout во Flutter строится по «сырым» размерам контейнера.

Важная оговорка: ExoPlayer в целом знает про pixelWidthHeightRatio,
но в типичном Flutter-стеке эта информация до Dart просто не доезжает или не используется.
На практике эффект один — SAR потерялся по дороге.

А что на iOS?

iOS (AVPlayer / AVFoundation) в среднем “умнее” в таких вещах и часто сам разруливает SAR и трансформы.
Поэтому в QuickTime всё и выглядит нормально.

Но дальше включается кроссплатформенность:
Flutter-плагин video_player пытается унифицировать API между платформами и в итоге часто отдаёт наверх просто размер кадра, без метаданных о том, как его правильно растягивать.

Получается классический «глухой телефон»:
на нативе всё понятно, а на уровне Flutter — уже нет.

Можно ли взять другой плеер

Да, есть flutter_vlc_player, который использует libVLC.

Он показывает такое видео корректно, потому что применяет SAR сам.
Но есть нюанс: libVLC не работает в Android Emulator.

Он ожидает:
реальное железо
нормальный GPU
полноценный surface
Эмулятор этого не даёт.
на реальном устройстве — всё ок
в эмуляторе — нет
В итоге получается вилка

Либо - стандартные Flutter-плееры
всё работает в эмуляторе
видео искажено

Либо - VLC
картинка правильная
эмулятор мёртв

Одновременно получить и то и другое нельзя.

Важно: это не баг конкретной библиотеки

Это архитектурное ограничение:
Flutter Video API сильно упрощён
ExoPlayer не экспортирует SAR/DAR наружу (в нашем сценарии)

anamorphic video плохо вписывается в mobile-first мир

Что в итоге решили
Видео перекодировать.

Привести всё к:
визуальному размеру “как должно выглядеть”

SAR = 1:1 (квадратные пиксели)
  • ❤ 1
Post #56 714
🙈 Разбор откликов на вакансию

Я разобрал все анкеты на позицию junior-разработчика и хочу зафиксировать несколько рекомендаций.
Это не «как понравиться», а как дать о себе нормальное представление.

Образование и опыт

Пишите конкретно.
Формулировки вроде:
«Высшее образование»
«1,5 года во Flutter»
не дают вообще ничего.

Мне важны зацепки, по которым можно понять ваш уровень:
где учились и чему именно,
в каком контексте писали код,
с какими задачами сталкивались.

Если у вас нет профильного образования — это не приговор.
Но тогда у вас должно быть что-то, что:
можно указать,
можно проверить,
выделяет вас среди десятков людей, которые «изучают Flutter полгода».

Курсы, сертификаты, программы, школы — что угодно, но конкретное.
Если их нет, займитесь их получением.

И да:
👉 указывайте названия компаний, если вы в них работали.
Даже если это небольшой стартап или студия — это опыт, и он важен.

Технологии и кейсы
Не нужно писать:
«делал авторизацию»
«использовал Clean Architecture»
«работал с Firebase»

Это дефолт, который не несёт информации.

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

Хороший ответ — это такой, по которому видно:
человек в этом ковырялся, а не просто видел в туториале.

Pet-проект

Pet-проект — это не:
что-то сделанное за вечер,
клон из YouTube,
«учебный проект для портфолио».

Pet-проект — это реальная штука, которой вы занимаетесь месяцами.

Лучше:
один живой проект
чем
десять болванок.

Сейчас нейросети могут сделать любой учебный проект с одного запроса.
Это не несёт ценности.

Если у вас нет нормального pet-проекта — начните его делать сегодня.
Это самый надёжный способ вырасти.

Прочие вопросы в анкете

Вопросы могут казаться:
странными,
непонятными,
«зачем это вообще».

Но если вы:
игнорируете их,
отвечаете «на отвали»,
то создаётся ощущение, что вы:
либо не заинтересованы,
либо пассивны,
либо потенциально конфликтны.

Это всегда минус.

Логические задачи

Я понимаю, что многие используют нейросети.
Но смысла в этом почти нет, если вы не понимаете, что написали.

Лучше:
написать решение своими словами,
даже если оно неполное,
но с ходом мысли.

Если вы попросили ИИ помочь — ок.
Но разберитесь в решении и объясните его нормально.
  • ❤ 5
  • 💩 2
Post #55 824
Всем привет. Коротко зафиксирую статус и планы на месяц.

DartWay сейчас проходит переход
от внутреннего инструмента к публичному использованию.
Поэтому фокус — на обратной связи и жёстком рефакторинге ради нормального Dev Experience,
а не на расширении функциональности.

В феврале планирую:
- опубликовать dartway_router на pub.dev
- провести открытый вебинар с разбором пакета и архитектурных решений

Формат простой: показываю, как и зачем это используется в реальных Flutter-проектах,
и отвечаю на вопросы по ходу.

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

Если есть конкретные запросы по темам — можете написать, посмотрю, что имеет смысл разобрать.
  • 🔥 3
Post #54 1.02K
Как у вас сейчас обстоят дела с навигацией во Flutter?

Я готовлю к публичному релизу наш внутренний роутер — обёртку над go_router,
которую мы обкатываем уже больше двух лет.

Хочу собрать реальные боли и кейсы, чтобы адекватно отразить их в документации и примерах.

Интересно:
какой роутер используете чаще всего?
с какими сложностями сталкивались?
что в текущем подходе раздражает или не устраивает?

Можно коротко, можно с примерами — всё читаю.
  • 👍 2
Post #53 932
Один из главных навыков разработчика — умение организовать время для глубокой работы

Не фреймворки.
Не языки.
Не количество часов за компьютером.

А способность регулярно входить в состояние, где ты думаешь, а не просто реагируешь на входящие.

Для себя я выделяю три ключевые составляющие.

1️⃣ График

Глубокая работа не случается «между делом».

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

Для меня это раннее утро:
голова свежая, мир ещё не требует внимания, мышление работает чище.

2️⃣ Концентрация

Во время глубокой работы нельзя отвлекаться.

Чаты, уведомления, соцсети, «на минутку гляну» — всё это мгновенно выкидывает из мыслительного процесса.

Контекст не переключается бесплатно.
Каждое отвлечение — это потеря глубины и качества решений.

3️⃣ Рабочее пространство

Среда либо помогает думать, либо мешает.

Чистый стол.
Удобная и предсказуемая среда разработки.
Нейтральная фоновая музыка или тишина.

Всё это нужно не для эстетики, а чтобы успокоить ум.

Потому что программист в первую очередь работает головой.
А код — это уже следствие качества мышления.

Если не создавать условия для глубокой работы,
можно быть постоянно занятым — и при этом слабо продвигаться вперёд.

Отзывается?
Поделитесь своими лайфхаками продуктивности
  • ❤ 5
  • 👍 1
Post #51 804
👨‍🎓 Почему не стоит использовать build-функции внутри виджетов

Часто встречаю в чужом коде (и нейросети регулярно предлагают) такой паттерн:
Widget build(BuildContext context) {
return Column(
children: [
_buildHeader(),
_buildContent(),
_buildFooter(),
],
);
}


На первый взгляд — разумно.
Обычно это объясняют «улучшением читаемости».

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

1. Отсутствие архитектурных границ

Правильный подход — выносить UI в отдельные виджеты и, по возможности, держать верстку в ui_kit.

При таком подходе:
- все необходимые данные явно передаются через параметры
- либо виджет сам слушает нужные ему состояния
class Header extends StatelessWidget {
final String title;
final bool isLoading;

const Header({
required this.title,
required this.isLoading,
});
}


Это заставляет:
✔️ явно определить зависимости
✔️ зафиксировать контракт
✔️ понимать, кто от кого зависит и что использует

build-функции работают иначе.

Они находятся внутри родительского виджета и:
❗️ имеют доступ ко всем его полям
❗️ могут читать и обновлять переменные стейта


В итоге:
- зависимости неявные
- границы ответственности размыты
- код начинает «протекать» между частями экрана

2. Отсутствие оптимизации
- Flutter эффективно работает за счёт дерева виджетов:
- изолирует rebuild’ы
- оптимизирует обновления
- переиспользует части UI

_buildHeader() — это не виджет, а обычная функция.

И для Flutter нет возможности изолировать пересборку

Любое изменение состояния
→ пересобирается весь build() целиком.

3. Файл начинает расползаться

На старте всё выглядит безобидно:
2–3 build-функции
~100 строк кода

Но со временем:
функции начинают использовать общие данные
появляется условная логика
части экрана начинают менять состояние родителя

Разделить это становится сложно, и каждый раз:

«проще добавить ещё одну функцию, чем делать рефакторинг»

В итоге - количество функций и длина файла растут вместе с проектом.
В нашей практике были виджеты до 3000 строк в одном файле, даже подумать о рефакторинге которого страшно.

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

Рекомендации команды DartWay

1. Не использовать build-функции и приватные UI-виджеты в том же файле
Они создают иллюзию структуры без реальных границ.

2. Дробить UI на отдельные виджеты
Каждый логический кусок интерфейса — отдельный класс с явными входными параметрами.

3. Максимально выносить UI в ui_kit
  • ❤ 4
  • 🔥 2
  • 👍 1
  • 👎 1
Post #50 744
Опыт ≠ стаж

В опросе я разделил junior, middle и senior только по стажу — и это, на самом деле, не совсем корректно.

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

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

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

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

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

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

Если откликается — интересно, какие ограничения сейчас кажутся самыми сложными в работе.
  • ❤ 1
Post #48 730
Джунов много. Работы мало. И проблема не там, где кажется

Я регулярно размещаю вакансию Flutter-разработчика.

За 2–3 дня приходит 200–300 откликов.
И это не боты — это живые люди.

На рынке сейчас огромное количество джунов и начинающих мидлов.
Им тяжело:
— найти первую работу
— выделиться среди десятков соискателей
— показать свою компетентность на собеседовании

Но вот что важно понять.

Даже если ты получил оффер — это только начало катастрофы.

Что я вижу почти с каждым кандидатом:

Разработчик может:
✅ реализовать фичу
✅ прикрутить интеграцию
✅ заставить «чтобы работало»

Но не может:
❌ встроить это в существующий проект
❌ сохранить целостность архитектуры
❌ соблюдать принципы программирования
❌ думать на перспективу

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

И самое грустное:
через пару месяцев этот код не понимает уже сам автор.

Почему так происходит?

Потому что интернет забит туториалами:
— сложные анимации
— кастомные виджеты
— эффектные UI-трюки

Но почти нет контента о том:
• как организовывать код
• как принимать архитектурные решения
• как думать проектом, а не экраном
• как писать код, который переживёт тебя

Flutter — это не проблема.
Проблема — в отсутствии системного мышления.

И именно это отделяет:
разработчика → от инженера
исполнителя → от ценного специалиста

В следующих постах буду разбирать:
— типичные архитектурные ошибки
— как справляться с запутанным кодом
— как быть полезным, а не просто генерить код

Если ты узнал себя — это нормально.
Вопрос только в одном: хочешь ли ты из этого выбраться.

Напиши в комментариях, на каком этапе ты сейчас:
junior / middle / senior
  • 👍 5
  • 🔥 1
Post #47
DartWay Ru | Flutter & Fullstack Dart pinned «Привет. Меня зовут Евгений Новиков. Я Flutter-разработчик и тимлид, руковожу студией мобильной разработки и параллельно развиваю собственный fullstack-подход на Dart. Этот канал — про Flutter и fullstack Dart в реальной разработке. Не туториалы и не абстрактная…»
Post #46 748
Привет. Меня зовут Евгений Новиков.

Я Flutter-разработчик и тимлид, руковожу студией мобильной разработки и параллельно развиваю собственный fullstack-подход на Dart.

Этот канал — про Flutter и fullstack Dart в реальной разработке.
Не туториалы и не абстрактная теория, а то, с чем мы ежедневно сталкиваемся в коммерческих проектах.

Здесь я пишу про:
— архитектуру без фанатизма
— как наводить порядок в коде
— где должна жить логика и состояние
— как не теряться в реальных задачах
— как выстраивать Flutter-проекты, которые живут и масштабируются

Канал подойдёт тебе, если ты:
— уже пишешь на Flutter
— чувствуешь хаос в коде или проектах
— хочешь больше системности и уверенности
— смотришь в сторону fullstack Dart-разработки

Мы в студии много раз проходили путь
от «как-нибудь работает» до поддерживаемых и масштабируемых решений.
Часть этих подходов и инженерных решений со временем оформилась в DartWay —
наш фреймворк и методологию.

Если тебе близок такой подход — оставайся.
  • 🔥 2
Post #45
Channel photo updated
Post #44
Channel name was changed to «Dart Way | Flutter & Fullstack Dart»
Post #43 763
Новая фича в dartway

Кстати - проект переехал в монорепо, все обновления там
https://github.com/dartway/dartway

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

Это вопрос удобства и безопасности

accessFilter - required nullable - чтобы вы про него точно помнили, но могли не запариваться, если пока неактуально
Post #42 658
Вышла новая версия Serverpod 3.0
https://serverpod.devpost.com/

Есть много интересных обновлений.
DartWay будет переезжать на новую версию Serverpod в январе и как раз на это время планирую релиз первой версии на pub.dev
  • 👏 2
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →