Отзывчивые приложения для Android

Перевод статьи Responsive Android Applications, автор - Chris Stewart

Введение

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

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

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

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

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

Размер экрана

Давайте рассмотрим размеры экрана на iOS. Есть три: 3,5-дюймовый iPhone, 4-дюймовый iPhone и iPad. Хотя iPad mini, конечно, меньше iPad, с точки зрения разработчика, он просто масштабируется. Для многих приложений разница в размере 3,5-дюймовых и 4-дюймовых экранов iPhone незначительно влияет, поскольку изменяется только высота.

Система рисования iOS использует точки, а не пиксели, поэтому статус сетчатки экрана или статус не сетчатки не влияет на макет. Макет является либо статическим (разработанным до точки для каждого устройства, программным путем, либо с использованием XIB-файлов конкретного устройства), либо динамическим (с использованием автоматической компоновки или авторезистирующих масок).

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

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

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

Файлы макета

Давайте подробнее погрузимся в систему компоновки. Файлы макетов представляют собой файлы XML, которые описывают ваш пользовательский интерфейс.

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:padding="14dp">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="username"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="password"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Login"/>
</LinearLayout>

В приведенном выше файле макета LinearLayout используется для Views линейного выравнивания. Мы указали три вида в LinearLayout: имя пользователя EditText, пароль EditTextи кнопку входа в систему.

Обратите внимание на атрибуты layout_width и layout_height атрибуты каждого представления в файле макета. Эти атрибуты используются для указания ширины и высоты представления. Мы использовали две константы в каждом из этих параметров: wrap_content и match_parent. Если wrap_content указано как высота представления, это представление будет точно таким же высоким, как и должно отображаться его содержимое. Если представление указывает match_parent как его атрибут width, это представление будет таким же широким, как и представление, содержащее его.

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

Самое важное отличие здесь от iOS заключается в том, что этот XML-файл макета и указанные в нем представления не имеют размера. Фактически, представления в этом файле макета не будут иметь никакого значения размера, связанного с ними, пока они не будут размещены на экране.

Плотность экрана

Другим аспектом изменчивости в Views на Android является плотность экрана. Как написать приложение, которое работает на любом экране плотности?

Как вы знаете, разработчики iOS имеют два размера: нормальный и сетчатый. Если используется @2x суффикс имени файла, система автоматически выбирает соответствующее изображение в зависимости от устройства.

Плотность экрана Android работает аналогично, но с большей изменчивостью. Вместо двух графических конвертов у разработчиков Android много. Наш стандартный размер ковша изображения mdpi, или средний dpi. Этот mdpiковш совпадает с обычным размером изображения iOS. Затем, hdpiили высокий dpi, в 1,5 раза больше mdpi. Наконец, xhdpiили сверхвысокий dpi, в 2 раза больше обычного размера, такой же, как размер сетчатки iOS. Разработчики Android могут воспользоваться другими кодами изображений, включая xxhdpi и xxxhdpi.

Квалификаторы ресурсов

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

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

Здесь, ic_launcher.png дублируется в следующих трех папках: drawable-hdpi, drawable-mdpi и drawable-xhdpi. Мы можем запросить имя изображения, ic_launcher и система автоматически выберет соответствующее изображение во время выполнения, в зависимости от конфигурации устройства.

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

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

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

Спады

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

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

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

Категория устройства

Последняя деталь для рассмотрения - как управлять категориями устройств на Android. Обратите внимание, что iOS имеет две различные категории: iPhone и iPad. Тем не менее, Android очень отличается, поскольку он имеет спектр категорий устройств, а различие между телефоном и планшетом может быть произвольным. Ранее упомянутая система квалификаций ресурсов используется для поддержки этого спектра размеров экрана.

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="@dimen/container_margin" >
    ...
</LinearLayout>

Обратите внимание на @dimen/container_margin значение. Это относится к именованному значению, хранящемуся в системе ресурсов. Мы можем определить базовое значение-размерность, которое используется по умолчанию:

В res/values/dimens.xml:

<resouces>
    <dimen name=”container_margin”>4dp</dimen>
</resources>

Затем мы создаем квалифицированную версию этого дополнения для планшетов:

В res/values-w600dp/dimens.xml:

<resouces>
   <dimen name=”container_margin”>96dp</dimen>
</resources>

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

Разделить вид

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

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

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

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

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

В res/layout/activity_home.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Это FrameLayoutопределяется containerидентификатором, который будет содержать основной вид для нашего приложения и будет содержать представление для нашего основного фрагмента.

Мы можем создать квалифицированную версию этого же файла для планшетных устройств:

В res/layout-sw600dp/activity_home.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
        <FrameLayout 
        android:id="@+id/container"
        android:layout_width="250dp"
        android:layout_height="match_parent" />
        <FrameLayout 
        android:id="@+id/detail_container"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" />
    </LinearLayout>

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

Вывод

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

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