как адаптировать приложение под разрешение экрана
Перевод: Настройка ваших приложений и игр для устройств с длинным экраном
Привет, Хабр! Представляю вашему вниманию перевод статьи Tuning your apps and games for long screen devices автора Fred Chung.
В последние месяцы растет тенденция к тому, что производители телефонов представляют новые устройства с длинным экраном (более 16: 9), многие из которых имеют закругленные углы. Pixel 2 XL и Huawei Mate 10 Pro — всего лишь два из множества примеров. Эти особенности экрана могут принести пользователям впечатляющий опыт, но они обращают внимание на приложения и игры, которые не используют экран длинного формата на новых устройствах. Поэтому для разработчиков важно оптимизировать такие экраны. Давайте посмотрим на соответствующую поддержку, предоставляемую ОС Android.
Оптимизация для экранов с длинным соотношением сторон
Большинство приложений, использующих стандартные виджеты пользовательского интерфейса, скорее всего, будут работать на этих устройствах. В документации Android уточняются методы для гибкой работы на экранах разных размеров. Однако некоторые игры и приложения с пользовательскими интерфейсами могут столкнуться с проблемами из-за неправильных предположений относительно определенных пропорций. Мы разделяем несколько типичных проблем, с которыми сталкиваются разработчики, поэтому вы можете обратить внимание на те, которые относятся к вам:
Targets API level 26 или выше: используйте атрибуты
Targets API level 25 или ниже: используйте метаданные
Обратите внимание, что максимальные значения соотношения сторон будут соблюдаться только в том случае, если ваши действия не поддерживают
Системные почтовые ящики в приложении используются когда объявленное максимальное соотношение сторон меньше экрана устройства.
Примите во внимание возможность использования параллельных действий
Устройства с длинным соотношением сторон обеспечивают еще больше возможностей использования нескольких окон, что может повысить производительность пользователей. Начиная с Android 7.0, платформа предлагает стандартный способ для разработчиков реализовывать многооконный режим на поддерживаемых устройствах, а также выполнять перетаскивание данных между действующими окнами. Подробнее см. В документации.
Тестирование имеет решающее значение. Если у вас нет доступа к одному из устройств с длинным экраном, обязательно проверьте на эмуляторе необходимые свойства экрана и разрешения, которые описаны в документации эмулятора.
Мы знаем, что вы хотите порадовать своих пользователей устройствами с длинным экраном. С помощью нескольких шагов вы сможете гарантировать, что ваши приложения и игры будут в полной мере использовать эти устройства!
Поддержка разных размеров экрана при разработке android приложений
Код, приведенный в уроке, взят из учебного приложения, в котором демонстрируются способы оптимизации для разных экранов. Вы можете загрузить его здесь и использовать части кода в собственном приложении.
В этом уроке описаны следующие аспекты обеспечения совместимости интерфейса с разными экранами:
Использование параметров wrap_content и match_parent
Если указать параметры «wrap_content» и «match_parent» вместо строго заданных размеров, в представлениях будет использоваться минимально необходимое место или они будут растягиваться на всю доступную длину и ширину соответственно. Например:
Например, вот так он выглядит в вертикальной и горизонтальной ориентациях. Обратите внимание на то, как размеры компонентов автоматически адаптируются к длине и ширине:
Рисунок 1. Приложение News Reader при вертикальной (слева) и горизонтальной (справа) ориентации.
Использование объекта RelativeLayout
На рис. 2 показано, как этот макет выглядит на экране QVGA.
Рисунок 2. Скриншот экрана QVGA (маленького размера).
На рис. 3 показано, как он выглядит на экране с большей диагональю.
Рисунок 3. Скриншот экрана WSVGA (большего размера).
Использование квалификаторов размера
Масштабируемые или относительные макеты, один из которых продемонстрирован выше, имеют свои ограничения. Хотя они позволяют создать интерфейс, способный адаптироваться к разным экранам за счет растягивания пространства внутри и вокруг компонентов, пользователю может оказаться не слишком удобно работать с таким интерфейсом. Поэтому в приложении должен использоваться не один масштабируемый макет, а несколько альтернативных вариантов для разных конфигураций экрана. Их можно создать с помощью квалификаторов конфигураций, которые позволяют оперативно выбирать ресурсы, отвечающие текущим параметрам экрана (например, разные варианты макетов для экранов разных размеров).
Многие приложения отображаются на больших экранах в двухпанельном режиме, при котором список элементов расположен в одной панели, а их содержание открывается в другой. Такой режим просмотра удобен на достаточно больших экранах планшетных ПК и телевизоров, однако на экране телефона эти панели следует отображать по отдельности. Для каждого режима просмотра нужно создать отдельный файл.
Использование квалификатора Smallest-width
Одной из проблем, с которой сталкивались разработчики приложений для устройств Android версий до 3.2, было слишком общее определение «большого» экрана. Это касалось устройств Dell Streak, первой модели Galaxy Tab и планшетных ПК с экраном размером 7 дюймов. Многие приложения требовалось по-разному отображать на разных устройствах (например, с 5- и 7-дюймовыми экранами), хотя они и относились к одной категории «больших» экранов. В Android версии 3.2 и более поздних доступен квалификатор Smallest-width.
Это означает, что на устройствах, минимальная ширина экрана которых не меньше 600 dp, будет выбран layout-sw600dp/main.xml (двухпанельный макет), а на экранах меньшего размера – layout/main.xml (однопанельный макет).
Использование псевдонимов макетов
Квалификатор Smallest-width работает только на устройствах Android 3.2 или более поздних версий. Для совместимости с более ранними устройствами по-прежнему следует использовать абстрактные размеры (small, normal, large и xlarge). Например, чтобы интерфейс открывался в однопанельном режиме на телефонах и в многопанельном на планшетных ПК с 7-дюймовым экраном, телевизорах и других крупных устройствах, подготовьте следующие файлы:
Последние два файла идентичны: один из них предназначен для устройств Android 3.2 и новее, а второй для более старых планшетных ПК и телевизоров на платформе Android.
Чтобы не создавать дубликаты файлов и упростить процесс поддержки приложения, используйте псевдонимы. Например, можно определить следующие макеты:
Затем добавьте следующие два файла:
Использование квалификаторов ориентации
Хотя некоторые макеты одинаково хорошо смотрятся в вертикальной и горизонтальной ориентациях, в большинстве случаев интерфейс все же приходится адаптировать. Ниже показано, как изменяется макет в приложении News Reader в зависимости от размера и ориентации экрана.
После того как все возможные макеты определены, остается сопоставить каждый из них с подходящей конфигурацией, используя квалификаторы конфигураций. Воспользуемся псевдонимами макетов:
Использование растровых изображений nine-patch
Чтобы интерфейс был совместим с экранами разных размеров, используемые в нем графические элементы также должны быть адаптированы соответствующим образом. Например, фон кнопки должен одинаково хорошо выглядеть независимо от ее формы.
Если использовать для компонентов, размеры которых меняются, обычные изображения, то они будут равномерно сжиматься и растягиваться, и результат будет далек от идеального. Решением являются растровые изображения формата nine-patch – специальные PNG-файлы, содержащие информацию о том, какие области можно растягивать, а какие нет.
Создавая растровые изображения для масштабируемых компонентов, обязательно используйте формат nine-patch. На рис. 4 показано обычное растровое изображение (увеличенное в 4 раза для наглядности), которое мы переведем в формат nine-patch.
Рисунок 4. button.png
Рисунок 5. button.9.png
Обратите внимание на черные пиксели по краям. Метки у верхней и левой границ обозначают те области, которые можно растягивать, а метки у правой и нижней границ – те, куда должно быть помещено содержание.
При применении этого фона к компоненту (с помощью android:background=»@drawable/button» ) изображение будет растянуто по размеру кнопки, как показано на рис. 6.
Рисунок 6. Кнопки разных размеров с файлом фона button.9.png в формате nine-patch.
Адаптация под различные экраны приложений Windows Store
Заметил, что у разработчиков возникает множество вопросов по поводу адаптации приложения под экраны различного размера. Для того чтобы была возможность предоставить ссылку, по которой есть необходимая информация, я и решил написать этот небольшой материал. Рассматривать буду не только приложения под Windows 8.1, будет затронута и разработка приложений Windows 10 UWP.
Ни для кого не является новостью то, что существует множество устройств с различными размерами и разрешениями экранов. Для устройства с небольшим экраном, но высоким разрешением необходимо изображение иного размера и качества, чем для устройств с большим экраном и тем же разрешением. Обусловлено это тем, что количество физических пикселей устройства не всегда совпадает с количеством реальных пикселей отображаемых системой/приложением.
Коэффициент масштабирования — это соотношение реальных пикселей устройства и отображаемых. При расчете этого коэффициента учитывается также стандартная дистанция, с которой пользователи смотрят на экран устройства.
В приложениях под Windows 8.1 поддерживается три коэффициента масштабирования: 100%, 140% и 180%. У Windows Phone 8.1 приложений различных коэффициентов масштабирования больше.
В эмуляторе Windows Store приложений, при изменении разрешения экрана вы можете увидеть и само разрешение, и значение коэффициента масштабирования рядом.
Процесс адаптации изображений похож на локализацию изображений. Для того, чтобы для различных разрешений брался верный вариант картинки необходимо внутри папки images создать 3 папки с именами: scale-100, scale-140, scale-180. Внутрь этих папок уже и добавляем изображения с одинаковыми названиями.
Если вы собираетесь хранить все файлы в одной папке, то вам необходимо будет добавить файлам картинок постфикс с указанием коэффициента масштабирования.
Соответственно, вам нужно будет создать 3 версии изображения. Если ваше стандартное изображение имеет 200 пикселей в ширину, то для масштабирования 140% нужно будет умножить ширину на 1,4. То есть вам нужно будет создать такое же изображение 280 пикселей в ширину. Ну и для масштабирования 180% нужно будет иметь такое же изображение шириной 200*1,8=360 пикселей.
Во время выполнения приложения оптимальное изображение выбирается автоматически, в зависимости от того, какое разрешение экрана у пользователя.
Если вы задаете файл изображения из кода, то вывести картинку верного разрешения вам может помочь следующий официальный сниппет, который исходя из значения DisplayInformation.GetForCurrentView().ResolutionScale определяет текущий коэффициент масштабирования экрана:
Используя эти возможности масштабирования изображений можно создавать приложения с гибкими не фиксированными в пикселях макетами, например, используя Grid и указывая в качестве размеров ячеек пропорциональные значения — *.
Адаптация макета приложения под размер экрана
Если содержимое вашего приложения размещено в элементе-контейнере Viewbox, то при изменении размера экрана ваше содержимое будет автоматически растянуто и масштабировано с целью заполнить все доступное пространство. Для того, чтобы растровые изображения при таком увеличении выглядели прилично, необходимо добавить несколько вариантов различного размера, как мы это только что рассматривали.
Размещение приложения внутри Viewbox – это один из предлагаемых вариантов адаптации приложения под различные экраны. Другим вариантом может быть скрытие элементов приложения или изменение их размеров. Рассмотрим работу с различными размерами приложения на примере режима snap.
Стандартно приложение Windows 8.1 может быть минимум 500 пикселей в ширину. В случае, если ваше приложение хорошо будет выглядеть и при более узком виде, либо его вполне можно использовать с другими приложениями, а также если желательно оставлять его как можно дольше в рабочем положении – вы можете установить ему минимальной шириной 320 пикселей. Сделать это можно, указав в редакторе манифеста минимальную ширину 320 или добавив в код манифеста атрибут MinWidth со значением width320 (кстати, в Windows 8 приложениях режим snap был как раз 320 пикселей)
Самым простым вариантом адаптировать приложение под различную ширину может быть императивная установка видимости/невидимости, а также ширины и высоты контролов в событии изменения размера экрана. Сделать это можно приблизительно так:
Но так делать можно в небольших приложениях, в которых вам не будет трудно перебрать все существующие контролы в коде C#. Для нормальных приложений лучше всего изменения внешнего вида хранить в XAML VisualState состояниях. Таким образом, можно предоставить дизайнеру возможность комфортного изменения макета в Blend. Следующий пример содержит те же изменения, что и предыдущий код:
Теперь в событии изменения размера окна мы можем перейти к нужному состоянию (в зависимости от текущего размера экрана):
Здесь для получения размера экрана в ширину и высоту мы опять использовали параметр SizeChangedEventArgs e.
В любой другой момент выполнения программы, ширину и высоту видимого окна приложения (так называемые эффективные пиксели, которые не зависят от размера экрана устройства) можно получить так:
Кроме эффективных пикселей есть еще и raw пиксели (англ. raw — сырой, необработанный) – реальное количество точек на экране или физические пиксели. Например, если экран устройства 1080 пикселей в ширину, то и количество raw пикселей будет 1080 по горизонтали.
Для получения физического размера окна приложения в дюймах (если по каким-то причинам вам вдруг понадобилась эта информация), вы можете использовать следующий трюк:
Что по поводу приложений универсальной платформы Windows?
Универсальные приложения Windows 8.1 уже предоставляли нам возможность сделать свою отдельную XAML раскладку для WP и для Store. На следующем скриншоте два MainPage.xaml файла:
В приложениях UWP нам будет доступна возможность создать множество XAML файлов с представлениями внешнего вида приложения и выбрать нужный из них, в зависимости от различных факторов (размер экрана, разрешение и т.п.). Давайте попробуем.
Создадим в проекте директорию DeviceFamily-Mobile.
Кликнем на ней правой кнопкой мыши и выберем пункт Add new item
Из вариантов нам нужно выбрать XAML View и назвать наше представление так же, как и называется то представление, которое мы хотим заменить. В простом случае это может быть MainPage.xaml.
Теперь тот XAML код, который мы внесем в файл MainPage.xaml, расположенный в папке DeviceFamily-Mobile будет отображен на мобильных устройствах. На десктопах же и иных устройствах будет отображен дизайн приложения из основного MainPage.
RelativePanel
Теперь нам стал доступен новый контрол RelativePanel, который позволяет создавать взаимосвязи положений между своими дочерними элементами.
Например, следующий код:
задает оранжевой кнопке положение под светло синей:
Пример взят отсюда.
AdaptiveTrigger
Windows 10 приложения не только поддерживают VisualState состояния, но и расширяют их новым функционалом. Во первых, теперь стало можно использовать триггеры для UI. А во-вторых, VisualStateManager теперь поддерживает Setters. Теперь отпала необходимость создавать 0-секундную анимацию (даже более того – устарела). Благодаря этому код становится более читаемым. Сравните следующий пример с примером, который мы рассматривали ранее:
Обратите внимание на строку Здесь задается значение минимальной ширины окна приложения, при котором сработает триггер. Далее с помощью Setters задается цвет для состояния. Весь этот код означает, что при изменении ширины приложения, в случае если ширина становится шире чем 600 пикселей цветом Layout становится зеленый.
Замечательная статья (англоязычная), из которой я взял это пример находится здесь.
Device preview toolbar
В Windows 10 ожидается расширение возможностей масштабирования приложений. Уже сейчас вы можете протестировать отображение внешнего вида вашего XAML кода на различных устройствах, используя device preview toolbar:
Обратите внимание на скриншот. Вы можете заметить, что Windows 10 приложения поддерживают гораздо больше коэффициентов масштабирования, чем приложения Windows 8.1. Вот табличка с презентации BUILD 2015, сравнивающая возможности масштабирования различных платформ:
Как вы можете заметить Windows 10 приложения на высоте – они самые «скалистые».
Что-то еще? Узнаем совсем скоро, ведь совсем не за горами 20-ое июля — дата релиза Visual Studio 2015, а там до 29-ого июля и выхода Windows 10 уже рукой подать.
Pixel-perfect верстка Android макетов
Разрабатывать интерфейс Android приложений — непростая задача. Приходится учитывать разнообразие разрешений и плотностей пикселей (DPI). Под катом практические советы о верстке макетов дизайна Android приложений в Layout, который совпадает с макетом на одном устройстве а на остальных растягивается без явных нарушений дизайна: выхода шрифтов за границы; огромных пустых мест и других артефактов.
UPD: Пост спорный, но много ценных советов в комментариях
UPD: Мне искренне жаль, я как маркетолог, не до конца разобрался с темой и не передал самую главную идею поста. Этот метод использовался на проекте, где заказчик предоставлял дизайн и его требованием было чтобы он выглядел максимально одинаково на всех устройствах. Исходя из этого и появился такой метод верстки, он спорный и подходит не всегда.
Используйте разные значения размера шрифта для разных разрешений экрана.
в values\dimens.xml text_size=16sp
в values-sw600dp\dimens.xml text_size=20sp
в values-sw720dp\dimens.xml text_size=24sp
Если нужно, присмотритесь к нашей идее в посте.
На iPhone layout задаются абсолютно и всего под два экрана iPhone 4 и iPhone 5. Рисуем два макета, пишем приложение и накладываем полупрозрачные скриншоты на макеты. Проблем нет, воля дизайнера ясна, проверить что она исполнена может сам разработчик, тестировщик или, даже, билд-сервер.
Под Android у нас две проблемы: нельзя нарисовать бесконечное число макетов и нельзя сверить бесконечное число устройств с конечным числом макетов. Дизайнеры проверяют вручную. Разработчики же часто понятия не имеют как правильно растягивать элементы и масштабировать шрифты. Количество итераций стремится к бесконечности.
Чтобы упорядочить хаос мы пришли к следующему алгоритму верстки. Макеты рисуются и верстаются под любой флагманский full-hd телефон. На остальных красиво адаптируются. Готовое приложение проверяет дизайнер на популярных моделях смартфонов. Метод работает для всех телефонов, для планшетов (>6.5 дюймов) требуются отдельные макеты и верстка.
Под рукой у меня только Nexus 4 возьмем его характеристики экрана для примера.
Макеты ненастоящего приложения-портфолио которые будем верстать (полноразмерные по клику).
Layout
Основную верстку делаем через вложенные LinearLayout. Размеры элементов и блоков в пикселях переносим с макета в weight и weightSum соответственно. Отступы верстаем FrameLayout или в нужных местах добавляем Gravity.
Для примера сверстаем ячейку списка приложений:
Дальше нам потребуется много DisplayMetrics-магии, напишем для него static helper.
1184 это высота Nexus 4 без кнопок, 768 — ширина. Эти значения используются, чтобы выяснить во сколько раз высота и ширина устройства, на котором запущено приложение, отличаются от эталонного.
ScrollView и List
Подход с weightSum не примемим к прокручивающимся элементам, их внутренний размер вдоль прокрутки ничем не ограничен. Для верстки ScrollView и List нам потребуется задать их размеры в коде (130 — высота элемента списка).
И дальше можно применять трюк с weightSum.
Картинки
Размер иконок приложений задается в коде:
Где 240 высота элемента списка, 20 высота отступа сверху и снизу.
Шрифты
Андроид не предоставляет единицу измерения пропорциональную размеру экрана. Размеры шрифтов рассчитываем на основании диагонали устройства:
Да, размеры шрифта придется задавать в коде (36 размер шрифта в пикселях на оригинальном макете).
Советы по работе с графикой
1. Используйте Nine-patch везде где возможно, где невозможно — перерисуйте дизайн.
2. Простые элементы рисуйте с помощью Shape
3. Избегайте масштабирования изображений в runtime
Nine-patch это графический ресурс содержащий в себе мета-информацию о том как он должен растягиваться. Подробнее в документации Android или на Хабре.
Nine-patch нужно нарезать под все dpi: ldpi mdpi tvdpi hdpi, xhdpi, xxhdpi. Масштабирование ресурсов во время работы приложения это плохо, а масштабирование Nine-Patch приводит к неожиданным артефактам. Ни в коем случае не задавайте в Nine-patch отступы, они оформляются отдельными элементами layout, чтобы растягиваться пропорционально контенту.
Shape
Если ресурс легко раскладывается на простые геометрические фигуры и градиенты лучше вместо нарезки использовать xml-shape. Для примера нарисуем фон рамку вокруг проекта в списке, которую мы выше нарезали как Nine-patch.
Картинки
Масштабирование графики силами Android трудоемкая и затратная по памяти операция. Картинки внутри Android обрабатываются как bitmap. Например, наш логотип в размере 500×500 со сплешскрина распакуется в bitmap размером 1мб (4 байта на пиксель), при масштабировании создается еще один bitmap, скажем в 500кб. Или 1,5мб из доступных 24мб на процесс. Мы не раз сталкивались с нехваткой памяти в богатых на графику проектах.
Поэтому картинки которые нельзя описать ни Nine-patch ни Shape я предлагаю поставлять в приложении как огромный ресурс в папке nodpi и при первом запуске масштабировать изображение до нужного размера и кешировать результат. Это позволит нам ускорить работу приложения (не считая первого запуска) и уменьшить потребление памяти.
Для сложных ресурсов подгружаемых с сервера (иконки приложений на наших макетах) идеальный вариант если сервер будет отдавать картинки любого размера. Как, например, сделано на проекте Stream. Приложение просчитывает нужный размер картинки для экрана смартфона, где запущено, и запрашивает их у сервера.
P.S. советы придуманы и основа поста написаны нашим Android-гуру Лешей, огромное ему спасибо!
А как вы рекомендуете верстать макеты под Android? Сколько макетов рисует дизайнер? Как обращаетесь с графическими ресурсами?
Подписывайтесь на наш хабра-блог (кнопка справа вверху). Каждый четверг интересные статьи о мобильной разработке, маркетинге и бизнесе мобильной студии. Следующая статья (5 сентября) «C# async на iOS и Android»