[Flutter] 2 шага к построению адаптивной верстки Flutter-приложения

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
09-Мар-2021 17:31

В этой статье речь пойдет о том, как создать Flutter-приложение, которое умеет адаптироваться к разным экранам и ориентациям. Статья будет полезна как начинающим, так и опытным пользователям Flutter. Первые найдут шаблон для изучения, вторые — еще один взгляд на этот вопрос.Постановка задачи или проблемы адаптивной верстки“Делай то, что тебе нравится.” FlutterЗвучит как духовно обогащенный мотиватор, но это — реальный взгляд разработчиков фреймворка на эту проблему. У Flutter нет одного решения, “прибитого гвоздями”, здесь у разработчика полная свобода и возможность выбирать способ решения этих проблем (заодно и собрать грабли по пути). На данный момент Flutter поддерживает мобильные платформы (Android, iOS), Web (in beta channel), редко используется для desktop. Это значит, что приложение должно поддерживать широкий диапазон размеров устройств, плотности пикселей и ориентации. Также мобильное устройство (если оно не квадратное) может быть повернуто пользователем в портретную или ландшафтную ориентацию. Пользователи мобильных устройств любят и умеют это делать во время работы приложения, чтоб рассмотреть подробнее содержимое экрана. Так что, чтобы не разочаровывать пользователя, мы должны позаботиться о проблеме поворота экрана во время работы приложения.И при всем этом приложению желательно еще и работать, отображая информацию о своей жизнедеятельности, несмотря на характеристики и параметры устройства, на которое его занесло, и на то, какие действия с ним может совершать пользователь. “Смешать, но не взбалтывать.” Проблема мультиплатформенного дизайнаРедко встретишь дизайнера, который понимает проблемы мультиплатформенного дизайна. И задача дизайнера Flutter-приложения — приготовить такой коктейль из элементов мобильного дизайна, который не вызывает отторжения у пользователя. Ведь нужно как-то совместить эти элементы с привычным UX на платформах, на которых их раньше не было. Например, FAB (floating action button in material design) и другие элементы и подходы дизайна, привычные на мобильных платформах, на вебе и десктопе немного в новинку, и наоборот — приемы, привычные для веба, смотрятся диковато на мобилках.Обычно обновления дизайна происходят итерационно. Так, дизайнер вряд ли сразу выдаст окончательный вариант под все ориентации и разрешения. Поэтому нужно предусмотреть возможность добавления и изменения, не трогая то, что уже работает. Как это уже работает в AndroidПроблема и способы ее решения известны. На Android в свое время это называлось отзывчивый (responsive) дизайн. По этому поводу даже есть даже целые гайдлайны: Responsive UI - Layout (правда сейчас уже в архиве), Support different screen sizes.Как это выглядит на практике для разработчика? В самом начале существует один макет, к которому по мере необходимости добавляем макеты для разных по плотности пикселей устройств, а затем обе ориентации для каждого типа устройств. Далее эти макеты выбираются в зависимости от того, на каком устройстве (с каким разрешением) и в какой ориентации они работают. Для экранов с большой площадью обычно используют макеты с большим количеством информации, которую можно отобразить. Хороший пример — master/detail flow из шаблонов новых приложений в Android Studio. Это классика того, как рекомендуется работать с экранами большой площади in android way.Долго ли сказка говорится, начнем писать код. Для этого используем модную нынче методологию BDD. РеализацияПеред тем как писать код, опишем сценарии:
  • В пределах одного макета на разных устройствах с разной плотностью пикселей должно выполнятся масштабирование контента (как при использовании dpi указания размеров).
  • Я хочу иметь возможность добавлять макеты в любом порядке (сделали макет для landscape — отлично, используем его везде, сделали для portrait — отлично, автоматически подставляем его для портретной ориентации).
  • Я хочу иметь возможность добавлять макеты как в Android Studio для landscape, для portrait, для более широких экранов, для более узких.
  • Добавление новых макетов не должно влиять на существующие макеты.
  • Цепочка вызовов для созданного макета не должна без моего ведома изменяться со временем.
  • Я хочу, чтобы логика выбора макета не изменялась, ее не нужно было изменять при добавлении/удалении макетов.
  • Логика выбора должна быть одинаковой и предсказуемой.
Код примера, рассматриваемого в статье и пакет, его реализующий, находится по ссылкам:пакет: https://pub.dev/packages/sizer_modпример в папке example: https://github.com/NickZt/sizer_mod/tree/master/exampleИнициализацияНачнем с инициализации пакета. Вызов нашей MaterialApp оборачиваем в вызов инициализации виджета подстройки размеров виджетов под dpi экранов:
@override
Widget build(BuildContext context) {
return LayoutBuilder(
   builder: (context, constraints) {
     return OrientationBuilder(
       builder: (context, orientation) {
         SizerUtil().init(constraints, orientation);
         return MaterialApp(
Этот код находится в example lib\main.dartШаг 1. Настройка виджетов под изменяемое разрешение экранаМы хотим отображать виджеты на разных экранах наиболее близко к задуманному при первоначальном дизайне. Эта часть заимствована из библиотеки sizer и работает так же как в ней.
image_tooltip
image_tooltipТакже можно использовать следующий метод, основанный на SizerUtil.orientation свойстве для более вариабельной настройки параметров виджета. Пример:
appBar: AppBar(
title: SizerUtil.orientation == Orientation.portrait
     ? const Text('portrait')
     : const Text('landscape'),
),
На AppBar выдается заголовок с названием текущей ориентации. Этот код находится в example lib\screens\home_screen.dartПроверим соответствие сценариям.Этот способ выполняет наше пожелание из пункта 1 списка Перед тем как писать код, опишем сценарии: “1. В пределах одного макета на разных устройствах с разной плотностью пикселей должно выполнятся масштабирование контента (как при использовании dpi указания размеров)”.Шаг 2. Используем специализированный виджет для работы с разными разрешениями экрана и ориентациейПоддержка изменения ориентации и переключения виджетов под разные размеры (разрешения) экрана реализована с использованием виджета ResponsiveWidget. В его поля мы подставляем макет (виджет) для каждой пары разрешения/ориентации. В начале у него есть одно обязательное поле (по аналогии с default xml in android) landscapeLargeScreen. Дополнительные виджеты под другие значения разрешения/ориентации опциональны, т.е их можно добавить по мере появления:
  • landscapeMediumScreen
  • landscapeSmallScreen
  • portraitMediumScreen
  • portraitSmallScreen
  • portraitLargeScreen
В приведенном ниже примере с помощью виджета WelcomePage создается страница в ориентации landscape и строится макет с использованием прокрутки контента в вертикальной плоскости, а для ориентации portrait используется такой же виджет с таким же набором страниц, только контент прокручивается в горизонтальной плоскости:
body: ResponsiveWidget(
landscapeLargeScreen: WelcomePage(
   pageIndex: 0,
   scrollDirection: Axis.vertical,
   children: listOfPages,
),
portraitLargeScreen: WelcomePage(
   pageIndex: 0,
   scrollDirection: Axis.horizontal,
   children: listOfPages,
),
),
Для визуалов:https://github.com/NickZt/sizer_mod/raw/master/example/images/portrait_land_mob.gif
image_tooltiphttps://github.com/NickZt/sizer_mod/raw/master/example/images/portrait_mob.gif
image_tooltipМы получили экран, который имеет разные макеты для портретной и альбомной ориентации. Когда устройство меняет ориентацию, мы перестраиваем наш макет.Как мы обнаруживаем изменения ориентации? Мы смотрим на отношение ширины к длине страницы. И в зависимости от этого переключаем макеты.Проверим соответствие сценариямЭто выполняет наши пожелания, указанные со 2 по 7 пункт из Перед тем как писать код, опишем сценарии:2. Я хочу иметь возможность добавлять макеты в любом порядке (сделали макет для landscape — отлично, используем его везде, сделали для portrait — отлично, автоматически подставляем его для портретной ориентации). 3. Я хочу иметь возможность добавлять макеты как в Android Studio для landscape, для portrait, для более широких экранов, для более узких. 4. Добавление новых макетов не должно влиять на существующие макеты. 5. Цепочка вызовов для созданного макета не должна без моего ведома изменяться со временем. 6. Я хочу, чтобы логика выбора макета не изменялась и ее не нужно было изменять при добавлении/удалении макетов.7. Логика выбора должна быть одинаковой и предсказуемой.ВыводыПо рецепту из моей статьи можно приготовить приложение, в котором размер и ориентация экрана на всех 3-х платформах будут работать одинаково. Надеюсь, этот способ будет полезен и в вашем приложении. Буду рад общению по теме (и не потеме тоже :)) в комментариях.К статье добавил опрос, результаты которого помогут мне выбрать тип приложения, который я возьму в качестве примера для второй части статьи. В ней я собираюсь более подробно остановится на виджетах, помогающих сделать приложение отзывчивым. А также хочу рассказать о некоторых нюансах работы с ними в сравнении с элементами дизайна, принятыми в Android. Также хочу рассмотреть способы автоматического импорта дизайна из Figma. Код примера, рассматриваемого в статье, и пакет, его реализующий, находятся здесь:пакет: https://pub.dev/packages/sizer_modGit репозиторий: https://github.com/NickZt/sizer_modпример — в папке example: https://github.com/NickZt/sizer_mod/tree/master/exampleПолезные ссылкиResponsive UI - LayoutSupport different screen sizesFloating action button in material designCross-platform guidelinesDesktop and tablet navigationFlutter Web: Getting started with Responsive DesignDevelop A Responsive Layout Of Mobile App With Flutter
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_flutter, #_flutter, #_adaptive_design, #_blog_kompanii_epam (
Блог компании EPAM
)
, #_flutter
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 15-Май 17:57
Часовой пояс: UTC + 5