Примеры Flutter-проектов

KegelFit

Доработка существующего приложения.

Правки внешнего вида приложения: Так как заказчик - дизайнер, то трепетно следит, чтобы в приложении все было pixel perfect. Чтобы дизайн лучше совпадал с макетом, я предложил сделать скейлинг приложения, так оно считает, что у него одна и та же ширина на всех устройствах. Ширина приложения = ширине в макете. Реализовано с помощью подмены MediaQuery.

Рефакторинг старта приложения: В приложении несколько стадий загрузки: onboard, предложение покупки, предложение триал, напоминание о списании триал, разрешение уведомлений, предложение оценки приложения. Все эти этапы могут активировать из разных условий: какой запуск по счету, время первого запуска, состояние подписки и т д. Изначально не было общего механизма переходов и, например, экран разрешения уведомлений мог открывать из onboard или предложения о покупки. Я переписал эту часть - оформил в виде стейт-машин, где каждый роут отчитывается о выполнении перед bloc инициализации, а не решает куда нужно переходить дальше.

Молодая Арктика

Место встречи молодёжи всей Мурманской области. Новости из жизни молодёжи, события, пространства, вакансии волонтеров, магазин и прочий контент.

Личный кабинет, баллы, покупки и большое количество медиа-контента. В приложении 53 экрана.

Invent

Приложение для проведения инвертаризация с помощью чтения qr-кодов.

Небольшое приложение, для которого был развернут сервер (nodejs, express, parse server). В приложении можно зарегистрироваться и авторизоваться с помощью email и пароля. Email валидируется с помощью parse server, для которого был разработан адаптер к unisender. Также в приложении можно пакетно загрузить объекты инвертаризации из типового xls файла. Есть функция экспорта qr-кодов в pdf файл, для последующей отправки на печать.

SemesterRus

Приложение для изучения русского языка, как иностранного.

Для приложения был создан редактор страниц, с помощью которого верстались уроки, экзамены, тесты и другие текстовые материалы (например, 'о приложении' и 'пользовательское соглашение'). В редакторе можно добавлять картинки, видео, таблицы, текст, тест с выбором ответа, тест с сопоставлением вариантов ответа, задания с заполнением пробелов. Также можно создавать задания на тему урока с проверкой ИИ (gpt-4o) - диалоги, эссе.

С помощью редактора было добавлено около 1500 записанных аудио. В какой-то момент выяснилось, что многие из них недостаточно громкие и/или содержат тишину в начале и конце. Для улучшения качества звука было решено обрезать тишину. Для этого написал скрипт, который прошелся по всем файлам. С помощью ffmpeg замерил уровень громкости и увеличил его, где требуется и обрезал тишину.

Для проекта необходимо было добавить свыше 2000 изображений для слов и уроков. Их сгенерировал скриптом с помощью dall-e-3. Так как было довольно много мусора, то дописал раздел в админке для выбора изображений из pexels.com и unsplash.com.

NRK87.

Приложение для работы с трекерами, которые продаются вместе с детской одеждой бренда NRK87.

Главная функция приложения - карта с маркерами трекеров, которые нужно было отрисовать самостоятельно. Для это нужно скачать аватарку, нарисовать маркер в буфере в нужном размере (т к google_maps_flutter рисует маркеры в размер), сохранить полученное на диск (на будущее), массив байт передать в BitmapDescriptor.

Добро.будильник

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

Функция будильника оказалась не самой простой задачей для Flutter. Объединив ограничения ОС приняли решение использовать flutter_local_notifications, так как библиотека может показывать нотификации по расписанию. Для android в нативном проекте настроили показ Activity в полноэкранном режиме и дали возможность запускать ее на заблокированном экране. Для iOS сложнее: назначаем серию нотификаций (раз в 3 секунды в течении минуты). Довольно сложной задачей было настроить рекуррентные платежи с помощью tinkoff_acquiring, т к заведение карты складывается из нескольких запросов + использование WebView для прохождения 3-D Secure.

ProjectV и Coffeecell

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

В тот момент, когда начинали портировать проект с нативных платформ, еще не было готовой библиотеки капчи Geetest. Поэтому реализовали ее самостоятельно, в том числе с поддержкой Web (через вызов js.context.callMethod и установкой метода обратного вызова js.allowInterop) - на текущий момент официальная библиотека gt3_flutter_plugin этого не умеет.

В приложениях есть редактор публикаций, в которые можно поместить фото, видео, товары и делать галереи из всего этого. Для того, чтобы вставить медиа из тела поста, рисуем кнопку со скрепкой рядом с курсором, но только на пустой строке. Во Flutter нет удобного способа вычислить координаты каретки. Обычно рекомендуют использовать TextPainter с такими же стилями, паддингами и размерами, как у TextField, но не всегда он вычисляет точное положение каретки. Да и создание и расчет TextPainter накладная операция.

Изучив исходники Flutter, нашли способ добраться до RenderEditable через глобальные ключи и поля state-классов. У RenderEditable есть метод getLocalRectForCaret, который вычисляет положение каретки исходя из содержимого TextField - это легче и надежнее способа с TextPainter. Также написали тест, на случай, если однажды доступ к RenderEditable будет утерян во Flutter SDK.

Календарь

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

Когда делали фичу, нам стало интересно, насколько производительным будет фича с таким кол-вом объектов + плавными анимациями перехода между разделами неделя, месяц и год. Пробовали разные решение, в итоге мы рисуем все объекты через CustomPainter, а также кэшируем все TextPainter, так как их создание и расчет размеров является довольно тяжелой операцией. Анимации переходов работают на основе форка local_hero, отдельные элементы анимируются flutter_animate.

UME

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

В приложении есть раздел Магазин - это также переиспользуемая фича. Для UME и NRK87 это один конкретный магазин, для остальных приложений это набор разных магазинов (маркетплейс). Сущность магазина имеет свои настройки: цвета, пункты доставки самовывоза, распространение, возможность оплатить баллами из доступ кошельков. Экран оформления заказа динамически строится на основе настроек магазина и может включать до 6 разных запросов к серверу, эти данные могут зависеть от конкретного приложения. Например, в UME можно выбрать питомца, для которого происходит покупка - это позволит начислить баллы для питомца (внутренние 'очки').

Также для приложения UME мы впервые задействовали Rive. Я самостоятельно делал анимации для иконок в bottombar.

Страница сверстана с помощью Dart Jaspr