Отображение виджетов на экранах с разной плотностью (dpi)

Отображение виджетов на экранах с разной плотностью (dpi)

Приложении на разных плотностях выглядит по разному, что в принципе и понятно.

В случае с элементами drawable, надо создать папки с нужной плотностью типа res/drawable-mdpi/ и размеры элементов в пикселях умножать но соответствующий коэффициент.

В случае с layout, я так понял нужно делать также, складывать layout для нужных размеров - в нужные

В голове каша, но могу понять с чего начать и от чего отталкиваться! Как определить эту минимальную ширину, и как исходя из этого делать layout если макет сделан в пикселях, как их переводить в (dp).

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

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

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

Решение о том, требуется ли новый layout под какой-то тип устройства принимается из того, требуется ли другая КОМПОНОВКА виджетов на экране для этого устройства. Например, планшет имеет большой размер экрана и компоновка для телефона выглядит на нем слишком громоздко, поэтому следует разместить виджеты по другому.

Обычно требуется только ДВА layout (не включая разметку для альбомного режима, если такая отличается от портретного) - для всех телефонов и для планшетов (если вы не собираетесь включать в список поддерживаемых устройств смарт-часы и телевизоры). В последнее время, правда, еще выделяют и для планшетов две отдельных разметки - для 7-8 дюймовых и для 9-10 дюймовых отдельно. Если вы планируете разместить виджеты на 10" планшете по другому, для лучшего вида или отображения большей информации, используйте это разделение.

Так, для поддержки портретного режима на следующих устройствах: телефоны, планшеты 7-8", планшеты 9-10" вам потребуется три разметки:

Виджеты на разметке масштабируются под текущее разрешение и плотность, их размеры задаются, как правило, относительно размера экрана, а не в абсолютных значениях, через параметры относительных размеров:

  • wrap_content - занимать только необходимый размер для отображения контента в виджете
  • match_parent - занимать всю ширину (высоту) родительского контейнера
  • layout_weight - задать размер относительно "веса" элемента. Используется для пропорционального разделения размеров, чем больше "вес" каждого отдельного элемента относительно других с "весом", тем большее место он занимает
  • layout_gravity - позиционирование к какому-либо краю или по центру родительского контейнера
  • gravity - позиционирование контента внутри виджета к какому-то краю или по центру

Отдельно стоит упомянуть о таком мощном инструменте адаптивной верстки, как контейнер ConstraintLayout (пример использования), недавно разработанный Google и подключаемый, как отдельная библиотека. Контейнер имеет очень большие возможности по позиционированию и связыванию элементов разметки, а итоговый экран будет выглядеть одинаково на всех устройствах. Из недостатков относительная сложность и текущий статус бета-версии.

Так же применяют группировку с помощью "классических" компоновочных контейнеров: FrameLayout , LinearLayout , TableLayout , RelativeLayout (подробнее о контейнерах). Очень мощный инструмент компоновки - TableLayout - практически почти все можно сверстать в таблицу того или иного вида, контейнер позволяет разместить все отноительно друг друга и всего экрана в относительных величинах.

В некоторых случаях для определенных плотностей экрана требуется указать разные размеры, к примеру, отступов (маржинов или паддингов) - скажем на устройстве с плотностью MDPI маржин в 8dp будет смотреться вызывающе расточительным. Для таких случаев используется указание разных размеров в зависимости от плотности экрана - файл dimens.xml. Создаются папки /res/values/ с квалификаторами соответствующих разрешений (res/values-mdpi/), в которых в файле dimens.xml указываются размеры для параметров заданных динамически, в зависимости от плотности. В разметке указывается не абсолютное значение, а ссылка на файл с размерами:

res/values-mdpi/dimens.xml - маржин для плотности MDPI

res/values/dimens.xml - для всех прочих плотностей экрана

Отдельно по поводу размера текста.

Размер текста указывается в sp - плотности, не зависящей от масштабирования (например, android:textSize="26sp" ).

Вообще, системой предложено несколько дефолтных вариантов:

@android:style/TextAppearance.Small - меленький шрифт @android:style/TextAppearance.Medium - средний и тд.

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

Библиотека AppCompat предлагает более расширенный список размеров шрифтов: Body, Subhead, Headline, Display, Title и др. (гайдлайны по шрифтам)

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

Следующие разметки будут одинаково выглядеть на всех экранах:

  1. Три кнопки в ряд по горизонтали на всю ширину экрана (гайдлайны по кнопкам):

2. Список на весь экран, с кнопкой под списком, которая всегда видима при скролле списка:

Таких примеров можно приводить множество. Если вас интересуют еще конкретные компоновки (только по группировке отдельных элементов, а не как сверстать, как в Google Play), пишите в комментарии, добавлю пару штук

📎📎📎📎📎📎📎📎📎📎