Как с помощью Flutter достичь адаптивности приложений
Показываем на примерах Dart-кода, как в Flutter реализовать кроссплатформенный адаптивный дизайн для смартфонов, планшетов и больших экранов 📱💻🖥️
Что такое Flutter?
Flutter – это платформа разработки приложений от Google. Код может
выполняться на смартфонах и планшетах всех марок, а также настольных
компьютерах и ноутбуках в качестве нативных приложений или веб-страниц.
Как включить десктопную
и веб-разработку
Для включения поддержки
веб-разработки есть два способа:
установить Flutter, загрузив последнюю версию из архива SDK;
если Flutter уже установлен, переключиться на бета-канал с помощью $flutter channel beta, а затем обновить версию Flutter с помощью $flutter upgrade.
Далее запускаем следующее:
Чтобы включить
поддержку десктопной разработки, необходимо переключиться на master-релиз,
выполнив описанные выше действия. Запустите следующую команду, заменив <OS_NAME> на linux, windows или macos:
При возникновении проблем вот общие рекомендации по устранению:
запустите flutter doctor для проверки наличия проблем. Эта команда должна загружать любые необходимые компоненты;
запустите flutter upgrade;
перезагрузитесь – может быть это именно то, что вам нужно.
Запуск и создание
веб-приложений
Для старта разработки
под веб достаточно выполнить следующую последовательность действий:
должно появиться что-то
подобное:
Выполнение команды flutter run в совместимом Flutter-проекте приведёт к запуску Flutter
веб-сервера на localhost:<RANDOM_PORT> . Это позволит получить доступ к веб-приложению
Flutter из любого браузера.
Если у вас установлен Chrome, может потребоваться добавить переменную окружения
CHROME_EXECUTABLE в путь к исполняемому файлу Chrome.
Запуск и создание десктопных
приложений
После того как вы
включили десктоп-поддержку, можно запустить приложение Flutter на своей рабочей
станции с помощью flutter run-d <OS_NAME>, заменив <OS_NAME> тем же
значением, которое вы использовали при включении поддержки ранее. Также вы
можете создавать бинарники в каталоге сборки с помощью flutter build
<OS_NAME>.
Прежде чем приступить,
нужно иметь каталог, содержащий все необходимое для Flutter и вашей платформы. При создании нового проекта всё будет добавлено автоматически, а для существующего
проекта используйте команду flutter create. Linux и Windows API пока
нестабильны, поэтому, возможно, придётся заново сгенерировать папки для этих
платформ, если приложение перестанет работать после обновления Flutter.
Когда приложение
совместимо?
Проект не должен содержать
код или плагин, не имеющий конкретной реализации под определённую платформу, на
которой вы хотите всё это построить.
Например, вы можете
использовать пакет url_launcher
или пакет от Google – path_provider,
используемый для получения локального пути и сохранения файлов или пакет shared_preferences, для работы с локальным хранилищем HTML в
интернете.
Создание адаптивных
макетов
Как сделать своё приложение отзывчивым? Для этого нужно ответить на пару вопросов:
Какие виджеты используются и какие из них могут/должны помогать с адаптацией к экранам разных размеров?
Как получить информацию о размере экрана и использовать его при создании UI?
На первый вопрос мы
ответим позже. Давайте сначала поговорим о последнем, потому что с ним легко
можно справиться двумя способами:
Взять информацию из MediaQueryData, которая находится в дереве виджетов. Эту часть (MaterialApp/WidgetsApp/CupertinoApp) можно получить, как и любой другой InheritedWidget, с помощью MediaQuery.of(context). Он имеет свойство size, относящееся к типу Size с двумя свойствами width и height типа double.
Использовать LayoutBuilder (так же, как StreamBuilder или FutureBuilder), передающий функции builder (вместе с контекстом) объекту BoxConstraints со свойствами minHeight, maxHeight, minWidth и maxWidth.
А вот та же задача, но
с использованием LayoutBuilder:
Теперь подумаем о том,
какие виджеты могут подстраиваться к размерам.
Наиболее адаптируемый виджет
– это GridView. Он построен с использованием GridView.extent constructor и даже
не нуждается в нашем участии:
Вы можете разместить
содержимое различных размеров, изменив maxCrossAxisExtent.
Этот пример использует
GridView.extent GridView. Было бы разумнее применить GridView.builderвместе с
SliverGridDelegateWithMaxCrossAxisExtent – в этом случае виджеты,
отображаемые в сетке, динамически создаются из другой структуры данных:
Примером адаптированного
GridView к различным экранам является страница, представляющая собой простое
веб-приложение Flutter, состоящее из GridView и Cards.
Заменим Drawer с
постоянным меню слева:
Хранить меню, которое будет находиться внутри Drawer, можно в гамбургер-элементе. Альтернативы: BottomNavigationBar или TabBar в сочетании с TabBarView, но в
обоих случаях придётся внести больше изменений, чем требуется для Drawer.
Чтобы показать только
Drawer, содержащий меню, которое мы видели ранее на небольших экранах, нужен
код, проверяющий ширину с помощью MediaQuery.of(context) и передающий объект Drawer
в Scaffold только в том случае, если он меньше некоторого
значения ширины:
Теперь давайте
поговорим о Scaffold. В качестве примера основного содержимого приложения мы используем
всё тот же GridView, который хранится в виджете Content:
На больших экранах body может быть строкой, показывающей два виджета: меню
фиксированной ширины, и содержимое, заполняющее остальную часть экрана. На маленьких
экранах всё тело – это содержимое.
Обернём всё в
SafeArea и Center, потому что иногда виджеты веб-приложений Flutter, особенно
при использовании строк и столбцов, оказываются за пределами видимой области
экрана.
Это означает, что body в Scaffold
будет следующим:
А вот всё вместе:
Это основная часть
материала, который нам понадобится в качестве введения в адаптивный Flutter-UI. Теперь рассмотрим отзывчивость приложения со
стороны общих элементов приложения и UI-потоков.
Создание адаптивной
страницы входа
Экраны входа в систему
на мобильных устройствах обычно очень похожи друг на друга. Это просто столбец
с некоторым Padding вокруг виджетов, текстовыми полями для ввода логина/пароля
и кнопкой для входа. Стандартная страница входа в приложение
может выглядеть так:
Всё прекрасно смотрится
на мобильном устройстве, но очень широкие текстовые поля начинают выглядеть
раздражающе на планшете, не говоря уже о большем экране. Мы не можем просто
установить фиксированную ширину: телефоны имеют разные размеры экрана, нужно
поддерживать гибкость.
Например, мы установим
максимальную ширину в 500 и указали такие ограничения контейнера. Это приведёт
к тому, что поля будут «прилипать» к левой стороне экрана, что ещё хуже. Итак,
обернём центральный виджет:
Выглядит прекрасно, и не
пришлось использовать ни LayoutBuilder, ни MediaQuery.of(context).size. Теперь
попробуем отделить переднюю часть от фона. Изменяем цвет
фона и того, что находится за контейнером, но сохраняем белым передний план контейнера. На больших экранах не будем растягивать контейнер в верхней и
нижней части, а придадим ему закруглённые углы и сделаем анимированный переход.
Веб-приложения
позволяют изменять экраны на основе URL-адреса. Flutter поддерживает такую функциональность. Для этого нам нужно
изменить конструктор MaterialApp на следующий:
Теперь мы можем
переключиться на другой маршрут с помощью Navigator.pushNamed(context,
routeName) и Navigator.pushReplacementNamed(context,
routeName) вместо
Navigator.push(context, route) и
Navigator.pushReplacement(context, route).
Вот остальная часть
приложения. В DartPad вы не увидите именованных маршрутов в действии, поэтому попробуйте
самостоятельно.
Заключение
Надеемся, что данный материал дал представление о том, на что способен Flutter в отношении и смартфонов, и больших экранов. Это крутой фреймворк, простой в использовании, гибкий и
управляемый, позволяющий создавать современные приложения и имеющий превосходную кроссплатформенность.
Комментарии