Почему все строки в layout указываются косвенно из файла с ресурсами

Обновлено: 06.07.2024

В приложении Android контейнер компонентов имеет тип ViewGroup. Существует несколько разновидностей классов, наследующих свойства ViewGroup и определяющих структуру расположения компонентов в интерфейсе : LinearLayout, RelativeLayout, FrameLayout, TableLayout, ConstraintLayout и т.д. Отличия этих классов связаны с упорядочиванием компонентов :

• ConstraintLayout позволяет привязывать компонент к границам экрана или к другим компонентам.
• LinearLayout позволяет размещать View-компоненты в виде одной строки (horizontal) или одного столбца (vertical).
• RelativeLayout настраивает положение каждого компонента относительно других.
• AbsoluteLayout использует для каждого компонента явную позицию на экране в системе координат X, Y.
• TableLayout отображает элементы в виде таблицы, по строкам и столбцам.

Рассмотрим вопрос привязки компонентов в ConstraintLayout. Для этого создадим новое приложение p02layout по типу и подобию, описанному на странице Модули Android.

Привязка компонента в ConstraintLayout

Во вновь созданном проекте p02layout откроем модуль activity_main.xml в режиме Design и удалим включаемый по умолчанию компонент TextView с текстом «Hello World!», поскольку ему не требуется привязка; она создана студией. После этого добавим новый компонент TextView из палитры (Pallete) в интерфейс окна.


Если переключиться на текстовое представление модуля activity_main.xml, то можно сразу же увидить, что :

  • в качестве контейнера компонентов студия использовала при создании приложения ConstraintLayout;
  • компонент TextView подчеркнут красной линией.

При наведении на TextView мышкой во всплывающей подсказке Android Studio покажет ошибку :

This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you add constraints.

Как добавить привязки?

Если выделить на экране TextView, то можно увидеть 4 круга по его сторонам. Эти круги используются для привязки компонента по горизонтали и вертикали. Напоминаю, что контейнер ConstraintLayout занимает весь экран и его края совпадают с краями экрана, а также он является родителем TextView.


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


После этого необходимо «схватить» компонент левой клавишей мыши и переместить вправо на требуемую величину (нижний скриншот). Обратите внимание на число под стрелкой, которое меняется при перемещении компонента. Это величина отступа TextView от объекта, к которому он привязан; в нашем случае от левой границы родителя ConstraintLayout.


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

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

«Привязка» компонентов между собой

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

Давайте разместим в интерфейсе новый компонент типа PlainText и привяжем его к компоненту TextView. Компоненты связываются между собой также соответствующими кругами на сторонах. Как только вы подводите стрелку «дочернего» компонента к «родительскому», то студия подсветит у родителя его круги. Останется только совместить стрелку с кругом. После этого можно привязанный компонент перетаскивать и менять его относительное удаление.


Удаление привязки

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

Исходный текст activity_main.xml

Исходный текст включает описания двух компонентов. Главный тег описания макета интерфейса представлен типом android.support.constraint.ConstraintLayout. Идентификатор компонента в описании обозначается атрибутом android:id. Остальные параметры (атрибуты) определяют размеры, относительные положения и специфические свойства компонента.

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


Шаблон LinearLayout

Прежде чем переходить к линейному макетированию компонентов заглянем в основной класс приложения MainActivity.java.

Класс MainActivity.java имеет метод onCreate, который вызывается, когда приложение создает и отображает Activity. В первой строке метода происходит обращение к суперклассу. А вот во второй строке метод setContentView(int) фоормирует интерфейс Activity из layout-файла. В качестве аргумента методу передается не путь к layout-файлу (res/layout/activity_main.xml), а идентификатор файла ID.

Создадим новый layout. Для этого выберем пункт меню New => XML => Layout XML file. Любители горячих клавиш могут использовать второй способ : при выделенной папке res/layout нажать ALT+Insert, и там уже клавишами выбрать соответствующий пункт.


Во вновь открывшемся окне необходимо определить наименование XML-файла макетирования интерфейса и выбрать тип (Root Tag).


После определения имени linear в папке layout должна появиться новая запись (linear.xml). Все файлы XML, связанные с настройкой интерфейса, размещаются в директории приложения res/layout.


Теперь откроем файл linear.xml в режиме Design и разместим в интерфейсе три кнопки. При перетаскивании первой кнопки, Вы увидете, что она заняла весь экран по ширине. После перетаскивания второй кнопки размер первой уменьшился наполовину. И так далее. На скриншоте можно увидеть положения кнопок в интерфейсе. Кроме этого, в панели дерева (Component Tree) родителем кнопок является контейнер LinearLayout.


В исходном коде файла linear.xml (вкладка Text) можно посмотреть описание интерфейса :

Положение с горизонтального без каких-либо проблем можно изменить на вертикальное. Для этого следует либо в тексте файла linear.xml переопределить атрибут «android:orientation» на "vertical", либо в панели атрибутов установить соответствующее значение, как это представлено на скриншоте.


Чтобы стартовать приложение с шаблоном интерфейса linear.xml необходимо в метод onCreate класса MainActivity.java внести изменения во вторую строку : setContentView(R.layout.linear). Интерфейс работающего приложения с линейным контейнером расположения компонентов LinearLayout представлен на скриншоте.


Если Вы полностью самостоятельно повторили все действия, связанные с привязками компонентов в контейнерах типа ConstraintLayout и LinearLayout, то Вам не составит труда выполнить подобные действия с контейнерами RelativeLayout и AbsoluteLayout.

Продолжение статьи с табличным расположением компонентов TableLayout представлено здесь.

На прошлом уроке мы выяснили, что Activity читает layout-файл и отображает то, что в нем сконфигурировано. Теперь выясним, откуда Activity знает, какой именно layout-файл читать. А еще в этом уроке находится подсказка, как зарегиться на нашем форуме ;)

В этом уроке мы будем поворачивать экран. Эмулятор версии 2.3.3, который мы успешно применяли и будем применять для тестирования наших приложений, имеет глюк. Он не хочет корректно поворачивать экран. Поэтому вспомните, плз, урок 3 и создайте еще один эмулятор версии 2.2, например. Соответственно при создании проекта, тоже указываем версию 2.2. Скрины сделаны на версии 2.3.3 - не обращайте внимания на это.

Создадим новый проект:

Project name: P0051_LayoutFiles
Build Target: Android 2.2
Application name: LayoutFiles
Package name: ru.startandroid.develop.LayoutFiles
Create Activity: MainActivity

При разработке каждому Activity сопоставляется одноименный java-класс (наследник класса android.app.Activity). При запуске приложения, когда система должна показать Activity и в дальнейшем работать с ним, она будет вызывать методы этого класса. И от того, что мы в этих методах накодим, зависит поведение Activity.

При создании проекта мы указывали, что надо создать Activity с именем MainActivity

При использовании старого визарда это выглядело так:


В новом визарде - чуть по другому. На одном экране галка, на другом - имя:



Мы попросили создать Activity и Eclipse создал нам соответствующий класс (в дальнейшем мы научимся их создавать самостоятельно).

Давайте посмотрим этот класс: откроем двойным кликом файл src/ru.startandroid.develop.LayoutFiles/MainActivity.java


В нашем классе мы видим, что реализован метод onCreate – он вызывается, когда приложение создает и отображает Activity (на onCreateOptionsMenu пока не обращаем внимания). Посмотрим код реализации.

Первая строка:
super.onCreate(savedInstanceState); – конструктор родительского класса, выполняющий необходимые процедуры, его мы не трогаем.

Нас интересует этот код:
setContentView(R.layout.main);

Метод setContentView(int) – устанавливает содержимое Activity из layout-файла. Но в качестве аргумента мы указываем не путь к нашему layout-файлу (res/layout/main.xml), а константу, которая является ID файла. Это константа генерируется автоматически здесь gen/ru.startandroid.develop.LayoutFiles/R.java.


Этот файл можно открыть и посмотреть, но менять его не стоит. В R классе будут храниться сгенерированные ID для всех ресурсов проекта (из папки res/*), чтобы мы могли к ним обращаться. Имена этих ID-констант совпадают с именами файлов ресурсов (без расширений).

Откроем res/layout/main.xml, посмотрим, что там


Запустим приложение и посмотрим что оно нам покажет


Все верно - Activity отобразил то, что прописано в main.xml.

Попробуем отобразить содержимое другого файла. Создадим еще один layout-файл, например myscreen.xml. Для этого выделим папку res/layout в нашем проекте и нажмем кнопку создания нового файла




В поле File вводим имя файла: myscreen.xml и жмем Finish.

Новый layout-файл должен сразу открыться. Добавим TextView и через Properties изменим его текст на: «Этот экран описан не в main.xml, а в myscreen.xml».

При этом Eclipse будет подчеркивать этот текст желтым цветом и ругаться примерно так: [I18N] Hardcoded string ". ", should use @string resource. Это он возмущен хардкодом, который мы тут устроили. Он хочет, чтобы использовали файлы ресурсов для всех надписей. Но пока что мы это не умеем, так что игнорируем эти предупреждения.



Обязательно сохраняем. Чтобы в R.java появилась новая константа для этого файла - R.layout.myscreen.

Теперь настроим так, чтобы Activity использовало новый файл myscreen.xml, а не main.xml. Откроем MainActivity.java и поменяем аргумент метода setContentView. Замените «R.layout.main», на «R.layout.myscreen» (ID нового layout-файла). Должно получиться так:


Сохраняем, запускаем приложение. Видим, что теперь оно отображает содержимое из myscreen.xml, т.к. мы явно ему это указали в методе setContentView, который выполняется при создании (onCreate) Activity


Layout-файл в виде XML

Открыв файл main.xml, вы видите его визуальное представление. Т.е. некий предпросмотр, как это будет выглядеть на экране. Снизу вы можете видеть две вкладки – Graphical Layout и main.xml. Откройте main.xml


Мы видим достаточно читабельное xml-описание всех View нашего layout-файла. Названия xml-элементов - это классы View-элементов, xml-атрибуты - это параметры View-элементов, т.е. все те параметры, что мы меняем через вкладку Properties. Также вы можете вносить изменения прямо сюда и изменения будут отображаться в Graphical Layout. Например изменим текст у TextView. Вместо ссылки на константу, вставим свой текст «Какой-то текст»


Сохраняем. Открываем Graphical Layout и наблюдаем изменения.



Обычно авторы учебников дают содержание layout-файлов именно в xml виде. Это удобно – вы можете просто скопировать фрагмент и использовать, и не надо вручную добавлять View-элементы, бегать по Properties и настраивать все руками. Я буду делать в своих проектах также.

Layout-файл при смене ориентации экрана

По умолчанию мы настраиваем layout-файл под вертикальную ориентацию экрана. Но что будет если мы повернем смартфон и включится горизонтальная ориентация? Давайте смотреть.

Изменим myscreen.xml. Добавим вертикальный ряд кнопок и изменим надпись.

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" >
<TextView
android:id = "@+id/textView1"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "Вертикальная ориентация экрана" >
</TextView>
<LinearLayout
android:layout_height = "wrap_content"
android:layout_width = "match_parent"
android:id = "@+id/linearLayout1"
android:orientation = "vertical" >
<Button
android:text = "Button1"
android:id = "@+id/button1"
android:layout_height = "100dp"
android:layout_width = "100dp" >
</Button>
<Button
android:text = "Button2"
android:id = "@+id/button2"
android:layout_height = "100dp"
android:layout_width = "100dp" >
</Button>
<Button
android:text = "Button3"
android:id = "@+id/button3"
android:layout_height = "100dp"
android:layout_width = "100dp" >
</Button>
<Button
android:text = "Button4"
android:id = "@+id/button4"
android:layout_height = "100dp"
android:layout_width = "100dp" >
</Button>
</LinearLayout>
</LinearLayout>

Обратите внимание - я добавил вертикальный LinearLayout и поместил в него 4 кнопки. Подробнее обсудим это на следующем уроке.

Запустим приложение. В вертикальной ориентации все ок.


Нажмем в эмуляторе CTRL+F12, ориентация сменилась на горизонтальную и наши кнопки уже не влезают в экран (эмулятор версии 2.3.3 глючит и смена ориентации срабатывает не всегда)


Т.е. нам необходим еще один layout-файл, который был бы заточен под горизонтальную ориентацию и в нашем случае вывел бы кнопки горизонтально.

Но как дать знать Activity, что она в вертикальной ориентации должна использовать один layout-файл, а в горизонтальной – другой? Об этом за нас уже подумали создатели Андроид. Необходимо создать папку res/layout-land, а в ней создать layout файл с тем же именем, что и основной. Этот файл будет использован в горизонтальной ориентации.

Создаем папку: правой кнопкой на res, New > Folder, Folder name = layout-land, жмем Finish.

Далее создадим файл res/layout-land/myscreen.xml и настроим его под горизонтальную ориентацию. Аналогично, как и в первый раз, жмем кнопку создания файла. Откроется визард.

Вводим имя файла: myscreen.xml



Визард может ругнуться, что есть уже такой файл - The destination file already exists. Это он углядел ранее созданный файл res/layout/myscreen.xml. Нам надо ему сообщить, что новый файл предназначен для папки res/layout-land, а не res/layout. Жмем Next

А здесь уже руками внизу допишите приставку -land, чтобы получилось res/layout-land



Как вариант, можно было руками не дописывать, а добавить из левого столбца в правый атрибут Orientation и указать ему значение Landscape. Визард все понял бы и сам дописал к пути приставку -land.

А мы сами дописали путь и визард сам добавил атрибут направо.

Жмем Finish и получаем готовый файл.


Поместите этот 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" >
<TextView
android:id = "@+id/textView1"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "Горизонтальная ориентация экрана" >
</TextView>
<LinearLayout
android:layout_height = "wrap_content"
android:layout_width = "match_parent"
android:id = "@+id/linearLayout1"
android:orientation = "horizontal" >
<Button
android:text = "Button1"
android:id = "@+id/button1"
android:layout_height = "100dp"
android:layout_width = "100dp" >
</Button>
<Button
android:text = "Button2"
android:id = "@+id/button2"
android:layout_height = "100dp"
android:layout_width = "100dp" >
</Button>
<Button
android:text = "Button3"
android:id = "@+id/button3"
android:layout_height = "100dp"
android:layout_width = "100dp" >
</Button>
<Button
android:text = "Button4"
android:id = "@+id/button4"
android:layout_height = "100dp"
android:layout_width = "100dp" >
</Button>
</LinearLayout>
</LinearLayout>

Запустим приложение. Activity читает layout-файл, который мы указывали в методе setContentView, т.е. myscreen.xml и отображает его содержимое. Переключим ориентацию CTRL+F12. Activity понимает, что находится в горизонтальной ориентации, ищет в папке layout-land файл myscreen.xml и использует уже его.


В этом уроке мы:

разобрали, откуда Activity знает, какой layout-файл надо читать и настроили его на чтение другого файла
рассмотрели layout-файл с другого ракурса – XML
узнали, какой layout-файл используется при смене ориентации экрана (горизонтальная/вертикальная)

В следующем уроке:

изучим основные виды layout: LinearLayout, TableLayout, RelativeLayout, AbsoluteLayout

Понимание, что используемый в программе текст это отдельный ресурс, такой же как изображения и звук, приходит на сразу. Но стоит несколько раз поменять имя программы в паре десятков файлов или заняться исправлением однотипной синтаксической ошибки в пяти, шести разных местах и необходимость хранить строки отдельно от кода становиться очевидной.
В Android работа со строковыми ресурсами сделана очень удобна и не вызывает поначалу никаких сложностей. В официальной документации она описана в статье String Resources. В файле project\res\values\strings.xml задаем строку и ее имя после чего в Activity загружаем строку по этому имени.
strings.xml
ProjectActivity.java
Эту же строку можно использовать в xml файле разметки формы (layout resource). Как это реализовано можно посмотреть, создав новый проект и открыв файл main.xml.

Описание ресурсов

Загрузка строк

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

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

Для формата строки используется следующая конструкция: %X$F.
X$ — номер подставляемого параметра. В основном тексте они обычно идут по порядку 1$, 2$, но в локализованных ресурсах могут меняться местами. Также позволяется использовать один парметр в строке несколько раз.
F — обычный идентификатор формата, такой 's', 'd'. Их полный список, включая форматрирование даты, описан в документации класса Formatter
Если в строке используется только один параметр, то X$ можно опустить. Если считать параметры неудобно, а проблем с локализацией не предвидится, то можно вернуться к стандартной схеме формата строки — для этого в описание элемента нужно добавить атрибут formatted со значением false. Следующие две строки форматируют текст одинаковым образом:

Загрузить строку по ее имени можно также как и любой другой ресурс. Для этого сначала нужно с помощью метода getIdentifier по имени строки найти ее id, а с этим номером уже работать обычным сопособом. Следующий пример загружает строку с именем «score_correct».

Android позволяет хранить в ресурсах массивы строк. Для этого используется тег string-array, который содержит внутри элементы item с конкретными строками. Вот сокращенный пример из документации Android, который иллюстрирует задание массива.
strings.xml
Кроме очевидного применения — удобная загрузка данных, string-array часто используют для иницализации UI элементов с выпадающим списком значений: Spiner и ListPreference. В этом случае обычно требуется использовать одну из строк массива, как значение по умолчанию. Сослаться в ресурсах на конкретный элемент массива мы не можем, но из ситуации можно выйти задействовав псевдонимы для ресурсов.
Элементы массива инициализируются, как обычные строки, а элементы item содержат только ссылку на них. Такая инициализация на самом деле черезвычайно удобна и я использую ее даже в тех случаях, когда обращение к конкретной строке не планируется — это гарантирует, что при локазации все массивы будут одинакового размера, даже если часть строк в них не будет переведена. Само описание массива при этом удобно вынести в отдельный ресурсный файл.
Переписанный с использованием псевдонимов пример выглядит так:

strings.xml
Полезное замечание: до версии Android 2.3 в реализации загрузки string-array была ошибка, которая позволяла загружать максимум только 512 элементов.

Системные строки

Локализация строк

Базовый механизм локализации ресурсов в Android позволяет легко решить практически все задачи с локализацией строк. Полное описание в документации Android можно прочесть здесь. В ресурсах вам необходимо создать новую папку с именем values-xx и поместить туда файлы со строковыми ресурсами из базовой папки values. xx — это двухсимвольный идентификатор языка (список поддерживаемых значений приведен в конце текста). После этого необходимые строки нужно перевести, остальные удалить.
Для более тонкой локализации можно задействовать механизм задания региона. К примеру, у вас в программе есть соглашение пользователя, переведнное на французкий язык, но в нем есть отличия между версией для Франции и версией для Канады. Чтобы реализовать эти отличия надо к папке values-fr добавить название региона в формате rYY, где YY — это двухсимвольное название региона. В данном примере получатся папки values-fr-rFR и values-fr-rCA. В них следует поместить ресурсный файл с необходимой версией соглашения пользователя, а все остальные строки на французском языке оставить в папке values-fr.
Регионы и язык можно указывать без всякой связи друг с другом. Так в папке values-ru-rJP будут храниться русские тексты для жителей Японии.

values/strings.xml
values-no/strings.xml
values-nb/strings.xml
Вы можете создавать ресурсы с какими угодно кодами для языка и для региона. Если операционная система не найдет нужного региона, то она возмет значения для текущего языка. Если не сможет найти язык, то возмет значения по умолчанию из папки values.

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

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

Приложение

Поддерживаемые языки до Android 2.3

Английский (en), Голландский (nl), Испанский (es), Итальянский (it), Китайский (zh), Корейский (ko), Немецкий (de), Немецкий (de), Польский (pl), Русский (ru), Французский (fr), Чешский (cs), Японский (ja)

Поддерживаемые языки начиная с Android 2.3

Арабский (ar), Болгарский (bg), Венгерский (hu), Вьетнамский (vi), Греческий (el), Датский (da), Иврит (iw), Индонезийский (in), Каталонский (ca), Латышский (lv), Литовский (lt), Норвежский-Букмол (nb), Португальский (pt), Румынский (ro), Сербский (sr), Словацкий (sk), Словенский (sl), Тагальский (tl), Тайский (th), Турецкий (tr), Украинский (uk), Финский (fi), Хинди (hi), Хорватский (hr), Шведский (sv)

Поддерживаемые регионы до Android 2.3

Австралия (AU), Австрия (AT), Бельгия (BE), Британия (GB), Германия (DE), Испания (ES), Италия (IT), Канада (CA), КНР (CN), Корея (KR), Лихтенштейн (LI), Нидерланды (NL), Новая Зеландия (NZ), Польша (PL), Россия (RU), Сингапур (SG), США (US), Тайвань (TW), Франция (FR), Чешская республика (CZ), Швейцария (CH), Япония (JP)

Поддерживаемые регионы начиная с Android 2.3

Болгария (BG), Бразилия (BR), Венгрия (HU), Вьетнам (VN), Греция (GR), Дания (DK), Египет (EG), Зимбабве (ZA), Израиль (IL), Индия (IN), Индонезия (ID), Ирландия (IE), Латвия (LV), Литва (LT), Норвегия (NO), Португалия (PT), Румыния (RO), Сербия (RS), Словакия (SK), Словения (SI), Таиланд (TH), Турция (TR), Украина (UA), Филиппины (PH), Финляндия (FI)Болгария (BG), Бразилия (BR), Венгрия (HU), Вьетнам (VN), Греция (GR), Дания (DK), Египет (EG), Зимбабве (ZA), Израиль (IL), Индия (IN), Индонезия (ID), Ирландия (IE), Латвия (LV), Литва (LT), Норвегия (NO), Португалия (PT), Румыния (RO), Сербия (RS), Словакия (SK), Словения (SI), Таиланд (TH), Турция (TR), Украина (UA), Филиппины (PH), Финляндия (FI), Хорватия (HR), Швеция (SE)

Update: Добавлен раздел о массивах строк, локализации строк, системных строках. Убран пример с использованием ресурсов для передачи данных между различными Activity.

Адаптивный layout — это layout, который предназначен для работы с различными размерами и ориентациями экрана, а также с различными устройствами, на различных языках и версиях Android.

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

Экстернализация ресурсов (вынесение данных во внешний файл)

Чтоб экстернализировать ресурсы, нужно хранить их отдельно от кода приложения. Например, вместо того, чтобы жёстко прописывать какую-то строку в коде, вам нужно дать имя строки и добавить её в файл strings.xml , который в Android Studio вы можете найти на панели Project > Android в папке res > values.

Во внешние файлы также необходимо выносить такие ресурсы, как иконки, layouts, drawables (графические объекты). Это позволит:

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

Группировка ресурсов

Сохраняйте все ресурсы в папке res. Сортируйте их по типу в отдельные папки внутри res. Для этих папок нужно использовать стандартизированные имена.

Например, на скриншоте ниже показана иерархия файлов для небольшого проекта, которую можно увидеть на панели Project > Android. Папки, которые содержат ресурсы этого проекта по умолчанию, используют стандартизированные имена: drawable, layout, menu, mipmap (для иконок) и values.

В таблице ниже перечислены основные стандартизированные имена папок ресурсов.

Стандартизированные имена папок ресурсов

  • arrays.xml для массивов ресурсов,
  • dimensions.xml для значений различных размеров в интерфейсах,
  • strings.xml , colors.xml , styles.xml |

Альтернативные ресурсы

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

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

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

  • resource_name — это имя папки для этого типа ресурса (см. табл. выше) Например, drawable или values.
  • config_qualifier определяет конфигурацию устройства, для которого будут использоваться ресурсы. Все возможные квалификаторы рассматриваются здесь (таблица 2).
  • Чтобы добавить несколько квалификаторов к одному имени папки, разделите их с помощью тире. Если вы используете несколько квалификаторов для папки ресурса, их нужно расположить в порядке их перечисления в таблице.

Примеры с одним квалификатором:

  • Строковые ресурсы, локализованные на японский язык, будут находиться в файле strings.xml внутри папки values-ja в папке res (сокращенно res/values-ja/strings.xml ). Строковые ресурсы по умолчанию (ресурсы, которые должны использоваться, когда не найдено специфичных для языка ресурсов) будут находиться в файле res/values/strings.xml . Обратите внимание, что XML-файлы имеют одинаковые имена, в данном случае — strings.xml .
  • Стили компонентов для API уровня 21 и выше будут находиться в файле res/values-v21/styles.xml . Ресурсы стилей по умолчанию находятся в res/values/styles.xml .

Пример с несколькими квалификаторами:

  • Layout-ресурсы, предназначенные для расположения элементов справа налево и использования в «ночном» режиме, будут находиться в папке res/layout-ldrtl-night/. Это правильное имя папки, потому что в таблице квалификатор для направления элементов указан до того, как указан квалификатор для ночного режима. Папка с именами квалификаторов в обратном порядке (res/layout-night-ldrtl) будет неправильной.

Создание альтернативных ресурсов

Чтобы создать папки альтернативных ресурсов в Android Studio, выберите Android на панели Project, согласно указателю на рисунке ниже.

Чтобы использовать Android Studio для создания новой папки альтернативных ресурсов для определённой конфигурации в папке res, придерживайтесь следующей инструкции:

  1. Убедитесь, что вы используете панель Project > Android, как показано выше.
  2. Щелкните правой кнопкой мыши по папке res и выберите New > Android resource directory. Откроется диалоговое окно создания нового ресурса.
  1. Выберите необходимые для данного набора альтернативных ресурсов тип и квалификаторы.
  2. Нажмите ОК.

Сохраните альтернативные ресурсы в новой папке. Обратите внимание, что альтернативные файлы ресурсов должны быть названы точно так же, как файлы ресурсов по умолчанию (например, styles.xml или dimens.xml ).

Основные квалификаторы альтернативных ресурсов

Ориентация экрана

Квалификатор ориентации экрана имеет два возможных значения:

  • port: Устройство находится в портретном режиме (вертикальном). Так, res/layout-port/ будет содержать layout-файлы, которые будут использоваться, когда устройство находится в портретном режиме.
  • land: Устройство находится в альбомном режиме (горизонтальном). Соответственно, res/layout-land/ будет содержать layout-файлы, которые будут использоваться, когда устройство находится в альбомном режиме.

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

Чтобы создать layout для альбомной ориентации и больших дисплеев, используйте layout-редактор. Для этого следуйте указаниям ниже:

  1. Откройте XML-файл (например, activity_main.xml ) в Android Studio. Появится layout-редактор.
  2. Перейдите на вкладку Design в нижней части редактора макетов (если он еще не выбран).
  3. Нажмите на кнопку Orientation in Editor на верхней панели инструментов.
  4. Выберите параметр Create Landscape Variation.
  5. Для альбомной (горизонтальной) вариации откроется новое окно редактора с файлом land/activity_main.xml . Вы можете изменить этот layout для альбомной ориентации, не изменяя исходную портретную (вертикальной) ориентацию.
  6. Перейдите в каталог res > layout из панели Project > Android, и вы увидите, что Android Studio автоматически создала для вас вариант с именем activity_main.xml (land) для альбомной версии activity_main.xml .

Версия платформы

Квалификатор версии платформы определяет минимальный уровень API, поддерживаемый устройством. Например, используйте v11 для API уровня 11 (устройства на Android 3.0 или выше).

Для работы изображений WebP требуется уровень API 14 (Android 4.0) или выше, а для их полной поддержки требуется уровень API 17 (Android 4.2) или выше. Если вы используете изображения WebP:

  • Поместите версии изображений по умолчанию в папку res/drawable. Эти изображения должны быть формата, поддерживаемого всеми уровнями API, например PNG.
  • Поместите версии изображений в формате WebP в папку res/drawable-v17. Если устройство использует API уровня 17 или выше, Android выберет эти ресурсы во время запуска приложения.

Локализация

Квалификатор локализации указывает язык и регион (опционально), который используется в приложении. Данный квалификатор представляет собой двухбуквенный ISO 639-1 код языка, за которым (опять же, опционально) следует двухбуквенный код региона (перед ним будет находиться строчная буква r).

Вы можете указать только язык, но только регион указать нельзя. Примеры:

  • res/values-fr-rFR/strings.xml
    Строки в этом файле используются на устройствах с французским языком во Франции.
  • res/mipmap-fr-rCA/strings.xml
    Строки из этого файла будут используются на устройствах с французском языке, но уже в Канаде.
  • res/layout-ja/content_main.xml
    Этот layout будет использоваться на устройствах с японским языком.

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

Ресурсы по умолчанию

Ресурсы по умолчанию определяют дизайн и контент по умолчанию для вашего приложения. Например, когда приложение работает на устройстве с языком, для которого вы не указали специфичный для него текст, Android загрузит строки по умолчанию из файла res/values/strings.xml. Если файл по умолчанию отсутствует или в нём отсутствует хотя бы одна критичная для работы приложения строка, то приложение просто не запустится и выдаст ошибку.

Ресурсы по умолчанию имеют стандартные имена папок ресурсов (например, values) без квалификаторов в названии папки или скобок после названий файлов.

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

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

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

Как правило, каждый экран в вашем приложении для Android связан с одним классом Java или Kotlin, известным как Activity. Этот термин можно перевести как активность или деятельность, но мы будем использовать термин активити, без перевода. Единственный экран с отображенным «Hello World» создается с помощью активити MainActivity.kt. Это активити было создано средой разработки, когда вы создали свой новый проект. Каждое видимое активити в приложении для Android имеет макет, который определяет пользовательский интерфейс для активити. Android Studio имеет редактор макетов, в котором вы можете создавать и определять макеты.

Макеты описаны в XML. Редактор макета позволяет вам определять и изменять макет либо путем кодирования XML, либо с помощью интерактивного визуального редактора. Вы можете переключаться между редактированием макета в XML и в редакторе визуального дизайна и создавать макеты любым способом.

1 . Редактор макета в Android Studio

Каждый элемент в макете представляет собой view, или представление. В этой задаче изучим интерфейс редактора макетов в Android Studio и разберемся, как изменять значения свойств для view.

Что вы узнаете

  • Как использовать редактор макетов.
  • Как установить значения свойств.
  • Как добавить строковые ресурсы.
  • Как добавить цветовые ресурсы.

Откройте редактор макета

Изучите и измените размер дерева компонентов

  1. Посмотрите на дерево компонентов в левом нижнем углу вкладки «Дизайн».
    На этой панели отображается иерархия представлений view в вашем макете.
  2. Отрегулируйте стороны панелей так, чтобы вы могли видеть все в Дереве компонентов.
  3. Щелкните значок «Закрыть панель» в правом верхнем углу дерева компонентов.Панель Component Tree закрывается.
  4. Верните панель Component Tree, щелкнув по вертикальной метке «Дерево компонентов» слева.Теперь, когда вы знаете, как изменять размер, закрывать и открывать панель Component Tree, пришло время изучить иерархии представлений view.

Исследуйте иерархии представлений view

Далее в этом уроке мы рассмотрим работу с ConstraintLayout более подробно.


  1. Обратите внимание, что ConstraintLayout содержит TextView.
  2. Просмотрите XML-код для макета, щелкнув вкладку « Текст » в нижней части вкладки «Дизайн».
  3. В коде XML обратите внимание, что корневой элемент <android.support.constraint.ConstraintLayout>. Корневой элемент содержит один <TextView> элемент.

Читайте также: