Приложения Android сталкиваются с рядом проблем, с которыми другие мобильные платформы могут и не столкнуться (пока). Android доступен на самых разнообразных аппаратных средствах, каждое из которых имеет различный размер экрана и плотность пикселей (DPI), иногда с физической клавиатурой, а иногда без сенсорного экрана (например, Google TV). Добавьте разные реплики пользовательского интерфейса в разные версии Android, и разработчик приложения может принять во внимание множество переменных. В этой статье мы рассмотрим различные механизмы, которые предоставляет Android, чтобы упростить эту задачу.
Основной макет
Пользовательские интерфейсы Android могут быть составлены программно, но чаще они определяются в файлах XML, а затем раздуваются тем действием, которое их использует. Пример файла макета показан ниже:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0"/> <LinearLayout android:gravity="center" android:paddingTop="5px" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#777"> <Button android:text="@string/addaccountbutton" android:id="@+id/addaccountbutton" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
Полученный виджет выглядит следующим образом (список содержимого, предоставленного программой):
Вместо того, чтобы указывать расположение пикселей, LayoutManager решает, как распределить пространство. Подсказки макета передаются в менеджер макета с использованием атрибутов XML. Если вы посмотрите на приведенный выше пример, то увидите, что верхний используемый макет представляет собой LinearLayout
с двумя дочерними представлениями, ListView
и другим LinearLayout
, который, в свою очередь, имеет единственный дочерний элемент Button
. Каждый компонент имеет атрибуты макета layout_width
и layout_height
, которые определяют, как они должны рассчитывать свой предпочтительный размер. В этом случае мы используем fill_parent
чтобы использовать как можно больше места, или wrap_content
чтобы просто быть достаточно большим, чтобы содержать его содержимое. Компонент ListView
также имеет атрибут layout_weight
для указания макету, что оставшееся пространство должно быть выделено этому компоненту.
Существует несколько доступных по умолчанию макетов, или вы можете определить свой собственный. Значения по умолчанию:
- LinearLayout — дочерние элементы располагаются горизонтально или вертикально, каждый из которых имеет вес макета для выделения дополнительного пространства.
- FrameLayout — все дети укладываются друг на друга, занимая все пространство
- RelativeLayout — позволяет размещать компоненты слева, справа и т. Д. Других компонентов или самой рамки.
- TableLayout — размещает компоненты в таблице
Макеты могут быть вложенными, что позволяет при необходимости создавать сложные макеты. Типичным примером может служить стандартный центральный компонент с границами снаружи. Это просто вертикальный LinearLayout
с горизонтальным LinearLayout
качестве его среднего потомка.
Работа с различными размерами экрана и ориентации
Пока что определение наших макетов было довольно простым. Однако бывают случаи, когда недостаточно просто указать макет как изменить размер. Компоновка, разработанная для портретного экрана, может выглядеть неправильно на альбомном экране, требуя другого макета. В Android это рассматривается с помощью селекторов ресурсов.
Ресурсы для приложения Android размещены в проекте в каталоге res
. Пример приложения может иметь структуру каталогов, которая выглядит следующим образом. Обратите внимание на последние две строки, оканчивающиеся на -en
и -it
как мы вернемся к ним.
/ Рез
/ RES / макет /
/res/layout-port/mainscreen.xml
/res/layout-land/mainscreen.xml
/res/drawable-hdpi/icon.png
/res/drawable-ldpi/icon.png
/res/values-en/strings.xml
/res/values-it/strings.xml
Когда ваше приложение запрашивает ресурс, оно пытается найти файл на основе атрибутов телефона. Например, если наш телефон находился в mainscreen
ориентации, когда был сделан запрос на макет mainscreen
, он сначала посмотрел бы в каталог layout-land
, а если бы не нашел его, переключился бы на основной каталог layout
.
Итак, чтобы иметь разный макет для портрета и ландшафта, мы просто создаем два файла с одинаковыми именами в директориях layout-port
и layout-land
соответственно. То же самое касается почти каждого ресурса в системе. Другими обычно используемыми селекторами являются плотность экрана или размер экрана.
ПРИМЕЧАНИЕ. Android 3.2 (Honeycomb) представляет новую схему выбора ресурсов. Дополнительные сведения см. В разделе « Объявление макетов планшета для Android 3.2» в статье «Поддержка нескольких экранов» в документации для разработчиков Android.
Еще одним полезным селектором является язык устройства. В Android строки можно абстрагировать в XML-файл, который затем можно интернационализировать. В примере макета в начале статьи текст кнопки определяется строкой reference @string/addaccountbutton
. Во время выполнения это значение будет просматриваться в values / strings.xml, но этот ресурс, как и все остальное, зависит от селекторов. Таким образом, мы могли бы использовать values-it/strings.xml
чтобы обеспечить итальянский перевод для приложения.
Темы и Стили
Последняя часть головоломки дизайна сводится к тематике. Мы не хотим повторять цвета и значения в нашем приложении. Так же, как HTML имеет CSS, Android обеспечивает возможность создания тем. Как обычно, темы определены в файле XML с именем res/values/styles.xml
. Пример файла стиля показан ниже:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="TitleTheme" parent="android:Theme"> <item name="android:windowTitleStyle">@style/WindowTitle</item> <item name="android:windowTitleSize">49dip</item> <item name="android:windowTitleBackgroundStyle">@style/CustomWindowTitleBackground</item> </style> <style name="CustomWindowTitleBackground"> <item name="android:background">@drawable/bluegradient</item> </style> <style name="largeText"> <item name="android:textSize">27sp</item> </style> <style name="ttButton"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:textColor">#ffffff</item> <item name="android:paddingTop">10dp</item> <item name="android:paddingLeft">10dp</item> <item name="android:paddingBottom">10dp</item> <item name="android:paddingRight">10dp</item> <item name="android:layout_marginTop">10dp</item> <item name="android:layout_marginLeft">10dp</item> <item name="android:layout_marginBottom">10dp</item> <item name="android:layout_marginRight">10dp</item> <item name="android:textSize">25dp</item> <item name="android:width">120dp</item> <item name="android:shadowColor">#000</item> <item name="android:shadowDx">2.0</item> <item name="android:shadowDy">2.0</item> <item name="android:shadowRadius">2.0</item> <item name="android:textStyle">bold</item> </style> <style name="greenButton" parent="ttButton"> <item name="android:background">@drawable/greenbutton</item> </style> <style name="redButton" parent="ttButton"> <item name="android:background">@drawable/redbutton</item> </style> <style name="blueButton" parent="ttButton"> <item name="android:background">@drawable/bluebutton</item> </style> </resources>
Стили имеют имя, могут наследоваться от других стилей и указываются как набор пар ключ / значение. Чтобы использовать стиль, просто добавьте атрибут style=@styles/stylename
к представлению, к которому вы хотите применить стиль. Например, большая красная кнопка может быть определена как:
<Button android:text="@string/addaccountbutton" style="@style/redButton" android:id="@+id/addaccountbutton"/>
Все остальные значения определяются стилем. Он не такой выразительный, как CSS, но он обеспечивает основу для того, что нужно.
Завершение
Так что у вас есть это. Android не имеет хорошего конструктора графического пользовательского интерфейса, но предоставляет мощные механизмы для предоставления интерфейсов, которые будут работать на различных устройствах. Внимательные читатели заметят, что подход к разметке компонентов очень похож на разметку документов HTML с использованием CSS. Любой, кто знаком с веб-дизайном, должен легко собрать представления Android. Лично я предпочитаю иметь возможность видеть полное определение в коде / XML.