Адаптивность

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

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

Встроенная адаптивность

Стандартные экраны Jmix используют компоновки и визуальные компоненты, которые адаптируются к доступному пространству и способу ввода. Например:

  • Главное меню сворачивается на узком экране.

  • На устройствах с сенсорным экраном компоненты datePicker и select отображают свои всплывающие окна в нижней части экрана.

  • Действия диалогового окна могут располагаться вертикально, если горизонтального пространства недостаточно.

  • В компонентах tabSheet и tabs появляется прокрутка.

  • Компонент formLayout может изменять количество колонок.

Проектирование адаптивных экранов

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

Контейнеры

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

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

Медиазапросы и запросы контейнеров CSS

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

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

<hbox classNames="view-toolbar" width="100%">
    <!-- Содержимое -->
</hbox>

Затем задайте компоновку для узкого экрана и правила для широкого экрана в CSS темы приложения:

.view-toolbar {
    flex-direction: column;
    align-items: stretch;
}

@media (min-width: 48rem) {
    .view-toolbar {
        flex-direction: row;
        align-items: center;
    }
}

Значение 48rem — это контрольная точка (breakpoint), то есть ширина, при которой изменяется компоновка. При ширине менее 48rem элементы управления располагаются друг под другом и растягиваются на всю ширину. При ширине 48rem и более они располагаются горизонтально и выравниваются по центру по вертикали. Вы можете определить несколько медиазапросов, если компоновке требуется более одного изменения.

Медиазапросы учитывают ширину окна браузера. Для области с изменяемым размером используйте запрос контейнера, чтобы применять CSS на основе ширины контейнера, а не окна браузера. Это позволяет компоненту адаптироваться независимо от того, где он размещён.

Перенос строк при промежуточных размерах

При промежуточной ширине компоненты могут не помещаться в одну строку. Разрешите их перенос на дополнительные строки:

<hbox id="viewToolbar" width="100%" wrap="true">
    <!-- Содержимое -->
</hbox>

В Java вызовите viewToolbar.setWrap(true).

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

Служебные классы Lumo

Приложения, использующие Тема Lumo, позволяют реализовать некоторые типовые адаптивные изменения с помощью служебных классов вместо собственного CSS.

Примените адаптивные классы в дескрипторе экрана:

<hbox classNames="flex-col md:flex-row" width="100%">
    <!-- Содержимое -->
</hbox>

В этом примере компоновка начинается как колонка и меняется на строку в контрольной точке md.

Подробнее об использовании см. Служебные классы Lumo. Доступные контрольные точки приведены в справочнике служебных классов адаптивности.

Отдельные мобильные экраны

По возможности используйте единый адаптивный экран для настольных и мобильных устройств. Это упрощает поддержку и помогает сохранять единообразное поведение интерфейса при разных размерах экрана. Однако некоторые экраны с большим объёмом данных не могут обеспечить одинаково эффективный пользовательский опыт на компьютере и мобильном устройстве с одной компоновкой. Рассмотрите создание отдельных экранов для настольных и мобильных устройств, если оба варианта требуют тщательно продуманного интерфейса или если взаимодействие принципиально различается. Например, сотрудникам, работающим с мобильных устройств, может потребоваться более короткий сценарий, меньше действий, доступ к камере и удобное управление с сенсорного экрана.

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

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

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

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

Компонент virtualList

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

Демо-приложение Wind Turbines использует этот приём для списка турбин:

<virtualList itemsContainer="turbinesDc" width="100%">
    <fragmentRenderer class="io.jmix.windturbines.view.turbine.TurbineCard"/>
</virtualList>

Скрываемые боковые панели

Скрывайте второстепенные элементы до тех пор, пока они не станут необходимы. Боковая панель обеспечивает доступ к ним, не занимая места на экране. Используйте sidePanelLayout для добавления такой панели в дескриптор экрана. Используйте Боковой диалог для создания боковой панели из кода Java.

Переключатель switch

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

Пошаговый wizard

Для длинных форм показывайте пользователю по одному шагу за раз. Предоставьте понятные действия Назад, Далее и Завершить и валидируйте текущий шаг перед переходом к следующему. Такой подход помогает сохранять фокус и упрощает заполнение формы по сравнению с длинной страницей, перегруженной полями.

В Jmix отсутствует специальный компонент мастера. В примере Wizard этот приём реализован с помощью tabSheet для навигации и фрагмента для каждого шага.

Drag and drop

Перетаскивание (drag and drop) может сделать перемещение, группировку или изменение порядка элементов более естественным на сенсорном экране и позволяет уменьшить количество видимых кнопок действий. Vaadin позволяет делать компоненты источниками и целями перетаскивания. См. подборку рецептов Drag and Drop.