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

А что именно  —  сейчас и разберемся. 

Простое приложение-счетчик (Counter)

Затраты по времени: 30 секунд (или время, требуемое для выполнения flutter create timer ).

Знакомый экран для тех, кто уже когда-либо работал с Flutter. Именно он появляется при создании любого проекта Flutter из CLI. Отметим важность данного отправного момента и тот особо примечательный факт, что демо-версия Flutter действительно что-то делает (в отличие от других фреймворков, ограничивающихся лишь выводом “Hello World!”).

Этот простой начальный экран знакомит с основными концепциями Flutter, такими как Scaffold, StatefulWidget и понятием “состояние”. Скачав и установив Flutter SDK, вы сможете запустить данный пример приложения на телефоне.

В процессе обязательно измените часть текста, нажмите на “Save” и на ваших глазах фреймворк выполнит горячую перезагрузку. Если вы рассматриваете Flutter для будущих проектов, то в дальнейшем эта функциональность сэкономит десятки часов.

Если легкие пути не для вас, то можно поразмыслить над тем, как сохранить и загрузить счетчик с помощью shared_preferences.

Простой секундомер/круговой таймер 

Затраты по времени: 1 день.

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

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

А так как Flutter отличается большим разнообразием готовых визуально интересных виджетов, то с его помощью нам гарантирован эффектный результат. Например, фреймворк предоставляет виджет CircularProgressIndicator, который отображает круговой индикатор выполнения. Другой виджет с именем Stack позволяет разместить виджеты друг поверх друга. Оба они помогают отобразить ход секундомера и одновременно наглядно представить посекундное заполнение внешнего кругового индикатора CircularProgressIndicator следующим образом.

API Flutter облегчает выполнение данной задачи. Подсчитываем количество секунд, истекших с момента нажатия пользователем кнопки “Go”, после чего применяем функцию .remainder к общему числу секунд, чтобы определить сколько из них осталось. Например, если прошло 80 секунд, то мы записываем 80.remainder(60), в результате чего получаем 20 секунд. При делении 20 на 60 вычисляем, что 20 секунд составляют приблизительно 33% от одной минуты, и используем этот показатель в качестве значения индикатора CircularProgressIndicator. Все просто. 

Далее рассмотрим пример такого приложения с пояснениями.

Stopwatch App Example

dartpad.dev

В примере все приложение умещается в 130 строк. Скопируйте код в Android Studio или VS Code, и он заработает. Обратим внимание на несколько моментов.

  1. Без метода setState ничего не происходит. Он нужен при каждом выполнении действий, изменяющих UI. Поэтому, когда мы запускаем или останавливаем таймер и хотим изменить иконку, вызываем setState
  2. Даже при написании простого приложения, благодаря таким виджетам, как Scaffold, мы получаем красивую панель App Bar с эффектом тени и возможность указать местоположение плавающей кнопки действия (Floating Action Button). 

Если хотите задачку посложнее, подумайте, как добавить таймер круга. В этом случае потребуется список значений длительности (<Duration>[]) для сохранения временных показателей предыдущего круга и отображение их в Column под основным таймером. Обновляя список значений длительности, мы должны сделать то же самое и в обратном вызове setState для изменения UI. 

Простой список дел 

Затраты по времени: 1 день.

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

Сначала для оформления внешнего облика и основы приложения по-прежнему понадобится Scaffold, а затем  —  ListView для отображения списка дел. Этот виджет принимает параметр children, который представляет список виджетов. Здесь мы соотносим классы данных с фактическими виджетами, например так. А примечательно то, что ListView автоматически предоставляет возможность прокрутки, если общее число children по вертикали превышает область просмотра устройства. 

Мы также задействуем функцию showDialog для активизации диалогового окна с “новой задачей” и обрабатываем возвращаемое значение диалога для добавления этой задачи к списку. В процессе применяется поставляемый с Flutter AlertDialog с красивой фоновой тенью и соответствующим модальным окном. Код, состоящий из 126 строк, легко копируется в выбранный редактор. Вы можете выполнить его и в телефоне.  

Simple To-Do List

dartpad.dev

Выбираем лучшее 

Если вы дошли до этого этапа, скопировали примеры кода в свой редактор и немного поэкспериментировали, то, вероятно, пришли к следующим выводам.

  1. Создать визуально привлекательное и удобное приложение оказывается не так сложно, как могло показаться. Благодаря падающим теням, волновым эффектам и инструментарию Material оно сразу приобретает презентабельный вид. 
  2. Горячая перезагрузка кого угодно сделает счастливым. 
  3. Бизнес-логика (то, что приложение делает) переплетается с UI (то, как приложение выглядит), что чрезвычайно затрудняет или исключает возможность тестирования. 

Рассмотрим третий пункт. Все верно: мы можем разработать и создать целое приложение (и даже довольно сложное), используя setState, и самостоятельно управлять его состоянием, но рано или поздно возникнут проблемы. Как юные послушные разработчики, мы должны пытаться писать код, который можно протестировать. Это значит, что логику UI необходимо отделять от бизнес-логики. Кроме того, нужно убедиться, что зависимости приложения можно сымитировать во время тестов.

Вот поэтому следует подумать о применении фреймворка управления состояниями, например паттерна bloc. 

Источник: bloc

Честно говоря, вряд ли удастся освоить этот паттерн за выходные. Ну и ладно  —  Рим тоже не сразу строился. Научиться управлять состояниями с помощью bloc  —  задача не из простых, но без этого вы не поймете принципы создания надежных приложений Flutter. 

Если мы с вами одного поля ягоды, то предвижу вероятные возражения: Зачем дополнительно изучать что-то типа bloc, когда с помощью Flutter можно нарисовать на экране все, что угодно? Зачем себя этим утруждать? Опять же, если вы, подобно мне, являетесь full-stack разработчиком и занимаетесь различными веб-аспектами, связанными с API, аутентификацией и т.д., которые нужно запоминать, то сомневаюсь, что вам захочется забивать голову дополнительной информацией. Кроме того, в начале статьи были обещаны проекты, которые можно выполнить за выходные, а с таким раскладом придется переносить их и на следующие. 

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

Прощайте вызовы setState вручную 

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

Bloc реализует концепцию тождества внутри страниц (или экранов). Визуальный слой определенного виджета представлен состоянием, по мере изменения которого библиотека bloc велит Flutter перерисовать этот виджет. Если состояние не изменилось, то перерисовка не назначается. В связи с этим происходит трансформация логики мышления: на смену “перерисовать при нажатии на эту кнопку” приходит “перерисовать при изменении информации на экране”. 

Когда пользователь нажимает на кнопку, новое событие отправляется в blocк для определенного виджета. Вы выполняете обычную бизнес-логику внутри bloc и выдаете новое состояние. bloc сравнивает его со старым состоянием, и при наличии изменения обновляет UI.

Тестируем в свое удовольствие 

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

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

Удивительное сообщество 

Для всех связанных с bloc аспектов существует канал Discord, в котором время от времени появляется Феликс, создатель паттерна flutter_bloc. Здесь разработчики делятся самым разнообразным опытом. Помимо этого, в свободное время они поддерживают эти бесплатные библиотеки. А какая там невероятная взаимопомощь! Однажды у меня возникла проблема с одним тестом, и я обратился к сообществу канала за помощью в ее решении. И сам Феликс сделал пул моего кода, устранил проблему и отправил пул-реквест. 

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

Примеры проектов с flutter_bloc

Затраты по времени: от 3 до 4 выходных.

Примеры проектов доступны на сайте bloc. Они помогут освоить паттерн за несколько предстоящих выходных. 

Широко распространенное приложение-счетчик, обладателем которого вы становитесь благодаря flutter create, создается с помощью паттерна bloc, и в качестве интересного дополнительного бонуса оно содержит кнопку “вычитание”. Данные обучающие руководства характеризуются более подробным изложением материала (т. е. вы не можете просто скопировать код в редактор), и на то есть веская причина. Они объясняют, что происходит, и заодно обучают работе с паттерном bloc. 

С его помощью написано и приложение для просмотра погоды, которое тоже доступно на сайте. Здесь вы узнаете, как создавать привлекательный UI для приложения Flutter и функциональность pull to refresh (обновление информации на экране при его касании), а также как работать с простыми формами (для текстовых полей и т. д.). Опять же, необходимо следовать этому руководству, поскольку оно объясняет принципы более сложных функциональностей пакета bloc. 

Отличных выходных 

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

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

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Lew C: 5 Flutter Projects You Can Do in a Weekend

Предыдущая статьяРуководство для начинающих по созданию с нуля сайта онлайн-курсов или e-коммерции
Следующая статьяПарсинг HTML из строки на Ruby On Rails