Популярно, доступно, полезно

Создаем адаптивный пользовательский интерфейс android


Содержание

Предисловие

Не много вещей способны так же раздражать, как приложение, которое хорошо выглядит на скриншотах в Google Play и совсем по-другому на вашем устройстве. Я не жду, что пользовательский интерфейс каждого приложения тестируется на 11 000+ устройствах Android, и, к счастью, этого делать не нужно, если вы создаете адаптивный пользовательский интерфейс android.

Более того, большинство этапов в разработке Android, создание адаптивного пользовательского интерфейса — это мультидисциплинарный акт: каждый должен решить, когда и как вносить изменения в свой интерфейс.

Выбираем когда вносить изменения

Адаптивный интерфейс — это просто пользовательский интерфейс, который реагирует на количество доступного пространства. В то время, когда может возникнуть соблазн подумать только о вашем устройстве или конкретном телефоне или планшете, Android воспринимает фразу «быть не одинаковым» как девиз: это непрерывный спектр устройств и размеров (то, с чем веб-разработчики и разработчики настольных компьютеров имели дело в течение многих лет!)

Система ресурсов Android предоставляет инструменты для предоставления альтернативных ресурсов на основе доступной ширины, высоты или наименьшей ширины — важные показатели, когда нужно менять наш пользовательский интерфейс на основе доступного пространства.

Ширина и точки останова

Ширина — это самое важное измерение при выборе момента, когда менять свой интерфейс. Это связано с тем, что ширина является основой для системы точек останова.

система адаптивности в макетах

«Точка останова» — это определенная ширина, при которой ваш адаптивный пользовательский интерфейс android может выглядеть совсем другим: реагируйте на появление дополнительного пространства, чтобы лучше использовать его. Это может быть небольшое отличие(чуть большие отступы) или более значительное изменение — см. раздел «что менять» ниже с множеством примеров.

Хорошим примером этого является линия 600dp: только на этом моменте вам следует рассмотреть возможность одновременного использования двух уровней иерархии контента (например, главного и подробного). Ниже этой точки и появляется высокая вероятность неприятно удивить пользователя.

Аналогично, чрезвычайно большие размеры после 1600dp — это подходящий момент для установки максимальной ширины для вашего пользовательского интерфейса: либо выравнивание по центру и увеличение полей, либо выравнивание всего интерфейса по левому краю.

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

Чтобы воспользоваться преимуществами выбора ресурсов на основе ширины, вы должны использовать префикс w. Например, макеты по умолчанию располагались бы в директории layout, а макеты для ширины 600dp или выше в layout-w600dp.

Высота

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

Ограниченная высота

Возьмем, к примеру, случай сплит-экрана 16:9 на мобильном устройстве: такая небольшая высота может превратить традиционно простые в использовании интерфейсы (например, вертикально-прокручивающийся контейнер) в сложное задачу.

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

Подобно классификации ресурсов по ширине, точно также для высоты используется свой префикс h, т.е. layout-h480dp.

Наименьшая ширина и не зависящие от вращения интерфейсы

Существует естественная тенденция думать о «доступном пространстве» на основе общего размера устройства(поэтому так легко придти к мышлению «давайте строить планшетный интерфейс!»). Но ни ширина, ни высота на самом деле полностью не охватывают размерное мышление — каждый из них отражает только одно измерение. Но не стоит переживать! Есть альтернатива layout-w600dp-h600dp: наименьшая ширина(smallest width) и layout-sw600dp.

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

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

Это особенно важно при подготовке к многооконному режиму в Android N

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

Если полагаться на portrait или landscape при смене своего интерфейса, вы и ваши пользователи будут очень удивлены, когда они изменят размер вашего приложения и доберутся до этого волшебного перекрестка между portrait и landscape. Убедитесь, что им не придется удивляться.

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

Выбираем что менять

Однако «когда» менять составляет только половину уравнения. Знать, что (и как) изменить, так же важно.

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

Раскрытие(Reveal)

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

Это особенно характерно для макетов. На меньшем экране может потребоваться конкретное действие пользователя (например, нажатие кнопки) для отображения редко используемых полей.

Отображение скрытого контента

Однако на большом экране все поля могут отображаться по умолчанию.

Как это сделать: создайте два макета с тем же именем, один в каталоге макета и один в layout-w600dp. Убедитесь, что любые вызовы findById() проверяют наличие нулевых значений для представлений, которые отображаются только в одном из макетов.

Преобразование(Transform)

Преобразование подразумевает не скрытие и показ элементов, а изменение формата или их стиля. Самый простой пример — это меню, в котором у вас есть элементы с showAsAction = «ifRoom» — когда есть дополнительное пространство, элементы превратятся из пунктов выпадающего меню в элементы панели инструментов — изменят свой стиль из текста в иконки.

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

Коллекции данных

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

Как это сделать: Воспользуйтесь атрибутом layoutManager у RecyclerView для перехода от LinearLayoutManager к GridLayoutManager без изменения какого-либо кода. Убедитесь, что представление, созданное в onCreateViewHolder(), также изменяется на той же контрольной точке, что и ваш layoutManager.

Разделение(Divide)

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

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

Шаблон с вкладками

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

Как это сделать: На небольших устройствах создайте свой пользовательский интерфейс, используя вкладки и ViewPager, предпочтительно с фрагментом для каждой вкладки. Основываясь на наименьшей ширине (помните, что вы хотите, чтобы она была согласованной между вращениями), используйте макет, который непосредственно добавляет каждый отдельный фрагмент.

Обратное течение(Reflow)

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

Обратное течение

Как это сделать: Если у вас есть динамический контент, рассмотрите возможность использования StaggeredGridLayoutManager и использование app:spanCount в XML или setSpanCount() для динамического изменения количества столбцов.

Примечание. Мы много говорили о том, как настроить макеты с помощью ширины, высоты и наименьшей ширины, но этот же метод применяется ко всем типам ресурсов. Вместо того, чтобы создавать отдельные XML-файлы только для изменения spanCount, сделайте его целым ресурсом и предоставьте альтернативное значение в папке ресурсов values-w600dp.

Расширение(Expand)

Не каждое изменение должно быть большим и радикальным: иногда небольшие изменения — все, что вам нужно. Простое расширение пространства пользовательского интерфейса(или добавление дополнительного поля), может быть эффективным способом изменить этот интерфейс.

Раскрытие интерфейса

Как это сделать: как упоминалось выше, любой ресурс может реагировать на изменения ширины, высоты и наименьшей ширины. Этот тип расширения на самом деле проще сделать, добавив отступ: представьте, что отступ 0dp для меньшего экрана и 24dp на больших устройствах. Другим решением будет использование Percent Support Library, например, меняя значение layout_widthPercent с 100% до 80%. Если вместо этого вы хотите установить максимальную ширину для всего представления, прочитайте эту статью о оптимизации длины строки, включающую MaxWidthLinearLayout.

Позиционирование(Position)

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

Рассмотрим FloatingActionButton (FAB). По определению этот элемент должен быть привязан к одному из основных действий, которое пользователь хотел бы совершить. В частности, если вы меняете другие элементы, рассмотрите следующие рекомендации по использованию плавающей кнопки действия на больших экранах.

Floating action button

Это может означать перемещение кнопки из своего «стандартного» расположения внизу справа для присоединения к дополнительному AppBar’у или к toolbar или к листу в самом макете.

Как это сделать: Предполагая, что вы используете FloatingActionButton с CoordinatorLayout, внизу справа с layout_gravity = «bottom|end», вам необходимо применить layout_anchor с дополнительным AppBarLayout и layout_anchorGravity=«bottom|end», чтобы связать кнопку с AppBarLayout, как описано в статье «Зависимости между представлениями в CoordinatorLayout».

Вперед, начните создавать адаптивные интерфейсы

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

Перевод статьи Building a Responsive UI in Android

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *