В Android системе почти всё, что не является Java кодом, является ресурсами. Ресурсы используются для определения цветов, изображений, макетов, строковых значений и т.д. Вы можете указывать значения в файлах ресурсов, а потом ссылаться на них в Java коде вашего приложения.
Все ресурсы находятся в папке res. Посмотрим, какие по умолчанию есть папки, файлы в каталоге res.
drawable – хранит в себе картинки, другие графические файлы.
layout – хранит все макеты приложения.
mipmap – хранит лого приложения, которое отображается в меню приложений.
values – хранит в себе разные ресурсы, такие как цвета, строки, стили, размеры.
Далее нам необходимо в верхнем левом углу поменять отображение проекта с Android на Project. Это позволит нам увидеть все папки, которые реально созданы в нашем проекте. Изначально мы не делали этого, чтобы не пугать вас :)
Можете заметить, что на самом деле в проекте несколько папок drawable и mipmap. Это папки для разных разрешений экранов, устройств, версий системы. Подробнее это обсудим в следующих уроках.
Ресурсы из папки res/values
Нажмём на папку values, посмотрим, что в ней находится:
colors.xml – содержит в себе все цвета.
strings.xml – хранит все строковые ресурсы.
styles.xml – хранит стили приложения.
Хранение таких данных в отдельных ресурсах дает нам гибкость и удобство при работе с проектом. Мы рассмотрим преимущества использования ресурсов на примере локализации – поддержки нескольких языков в приложении.
Файл string.xml. Локализация
Мы будем поддерживать два языка в нашем приложении: английский и русский. Для локализации приложения используют файл strings.xml. Туда помещается весь текст приложения, который должен быть подвержен локализации. Чтобы добавить поддержку ещё одного языка, надо создать папку с именем values-language. Т.к. мы поддерживаем русский язык, то создадим папку values-ru. Для этого нажмём правой кнопкой на папку res и выберем пункт New -> Android resource directory:
Directory name – values-ru
Resource type – values
Source set – main
Вот как это должно выглядеть:
После этого видим, что создалась папка values-ru. Отлично, создадим новый файл strings.xml. Для этого нажимаем правой кнопкой по папке values-ru, выбираем New -> Values resource file:
Затем появится окно, в котором необходимо ввести имя файла. Вводим strings. Теперь всё, что нам надо сделать – это добавлять ресурсы в эту папку с таким же именем, но значения мы будем писать на русском языке. Система автоматически будет брать значения из этого файла, если у пользователя на устройстве установлен русский язык. Для начала давайте посмотрим как выглядит обычный строковый ресурс:
sample_resource.xml
<stringname="имя_нашего_ресурса">В качестве значения идет любой текст</string>
У каждого строкового ресурса есть имя, по которому в дальнейшем будет идти обращение к нему, а также его значение. На самом деле так выглядят не только строковые ресурсы, а все ресурсы приложения:
Просто вместо типа ресурса string используются другие необходимые значения (color, dimen и т.д.). Теперь проверим, что это всё действительно работает. В файле values/strings.xml по умолчанию при создании проекта есть строка app_name:
Видим, что название ресурса app_name совпадает в двух папках. А вот значения мы можем указывать для каждого языка свои.
Доступ к ресурсам из XML
Теперь после создания строкового ресурса нам необходимо использовать его в layout файле. Ссылка на наш ресурс будет выглядеть так: @string/app_name. Но сейчас остановимся на минуту и разберём общий синтаксис при ссылке на файл ресурса из XML:
<имя_пакета> – имя пакета, в котором находится ресурс. Чаще всего его не будет, т.к. мы берём ресурсы из своего приложения. Если бы мы хотели взять строку из android библиотеки, то обращались бы @android:string.
<тип_ресурса> – тип ресурса, к которому мы обращаемся. В данном случае – string. Обратите внимание, что название отличается от названия файла strings – используется единственное число.
<имя_ресурса> – название ресурса.
Теперь, когда мы научились обращаться к ресурсам, давайте в файле activity_main.xml у TextView заменим текст на только что созданный строковый ресурс.
Запустим приложение и убедимся, что локализация действительно работает. После запуска приложения на эмуляторе, видим, что вывелась строка Resources, т.к. на эмуляторе стоит английский язык.
Давайте добавим русский язык и сделаем его основным. Для этого необходимо зайти в настройки системы и выбрать: System -> Languages & input -> Languages -> Русский. После добавления ставим русский язык первым:
Можем открыть приложение на эмуляторе или запустить его заново. Результат выглядит так:
Отображается надпись Ресурсы. Вот такое простое и элегантное решение предоставляет нам система для добавления поддержки новых языков. Стоит отметить, что помимо ручного заполнения файлов с ресурсами, существует возможность делать это через специальный редактор. Чтобы в него попасть необходимо, открыв файл со строковыми ресурсами (любого языка), в правом верхнем углу нажать кнопку «Open editor» (рус. Открыть редактор). Удобно использовать редактор, чтобы убедиться, что вы перевели все строки в приложении:
Вы можете заметить, что строка может быть нелокализируемой (поле untranslatable). Примером могут быть технические термины, которые не переводят на другие языки: IMAP, NFC, GPS. Для таких строк в файле strings.xml необходимо установить атрибут translatable="false". В файлах для остальных языков не надо дублировать эти строки.
Также к ресурсам можно получить доступ из Java кода. Посмотрим на синтаксис.
<имя_пакета>.R.<тип_ресурса>.<имя_ресурса>
Видим, что он очень похож на синтаксис доступа к ресурсу из XML. Параметры имя_пакета, тип_ресурса, имя_ресурса являются идентичными.
Доступ к нашему ресурсу можно получить так: R.string.app_name.
Когда приложение компилируется, автоматически генерируется класс R, который содержит идентификаторы для всех ресурсов в папке res/. Для каждого типа ресурсов существует вложенный класс (например, R.string для всех строк), и для каждого ресурса этого типа существует целое число (например, R.string.app_name). Из-за этого мы и можем получить доступ к ресурсу из Java кода.
Разберём на примере, как установить текстовый ресурс в TextView из Java кода:
Вначале мы связываем TextView из XML файла с Java кодом с помощью findViewById(R.id.text). Потом получаем строку, используя getResources().getString(R.string.app_name). После этого устанавливаем строку в TextView с помощью setText(appName). Запустите приложение и убедитесь, что логика локализации не изменилась.
Зачем работать с ресурс файлами из Java кода, если можно из XML?
Бывают ситуации, когда вы заранее не можете знать, какой ресурс вы хотите использовать. Например, если в соц. сети человек уже прочитал сообщение, то вы хотите отобразить “Прочитано”, в другом случае – “Отправлено”. Именно в таких случаях необходимо работать с ресурсами из Java кода.
В Android системе лучше по умолчанию использовать строковые ресурсы даже если вы поддерживаете только один язык, чтобы в дальнейшем не было проблем с локализацией. Чтобы у вас сформировалась хорошая привычка во всех дальнейших примерах мы будем использовать именно строковые ресурсы вместо обычных строк.
Файл colors.xml
Файл colors.xml хранит в себе цвета приложения. Это удобно, потому что вы храните (изменяете при необходимости) цвет в одном месте. По умолчанию создаются цвета, которые используются в нашем приложении. Добавим ещё два цвета:
Теперь представьте, что дизайнер сказал вам изменить цвет текста с чёрного на тёмно синий, а фоновый цвет – с серого на тускло жёлтый. Изменяем только значения в colors.xml:
С помощью getResources().getColor() получаем цвет, а используя setTextColor(), setBackgroundColor() устанавливаем цвета. В реальной жизни с этим часто приходится работать, когда в зависимости от статуса заказа товара в интернет-магазине изменяется фоновый цвет кнопки или контейнера.
Результат:
Всегда храните все цвета приложения в файле colors.xml, чтобы легче было вносить изменения. Также это необходимо для использования нескольких тем (дневной и ночной) в приложении.
Файл styles.xml. Стили
Файл styles.xml нужен для того, чтобы объединять повторяющиеся атрибуты элементов в стили. Давайте откроем файл styles.xml:
styles.xml
<resources>
<!-- Base application theme. -->
<stylename="AppTheme"parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<itemname="colorPrimary">@color/colorPrimary</item>
<itemname="colorPrimaryDark">@color/colorPrimaryDark</item>
<itemname="colorAccent">@color/colorAccent</item>
</style>
</resources>
По умолчанию в приложении создаётся стиль AppTheme, который задаёт основные цвета нашего приложения. Синтаксис создания стиля довольно простой:
<resources>
<!--Остальной код выше не изменился-->
<stylename="Text">
<itemname="android:layout_width">wrap_content</item>
<itemname="android:layout_height">wrap_content</item>
<itemname="android:layout_margin">10dp</item>
<itemname="android:textSize">25sp</item>
</style>
</resources>
И после этого используем этот стиль в файле activity_main.xml, устанавливая атрибут style, передавая ему ссылку на стиль @style/Text:
Теперь, когда мы захотим поменять размер текста или изменить, добавить любой другой атрибут, то поменяем его в стиле Text. Стили позволяют избежать дублирование кода.
Наследование стилей
Наследование с помощью слова parent
Теперь давайте усложним задачу. Пусть первый текст будет тёмно синим, а второй – тёмно зелёным. Мы можем воспользоваться наследованием стилей. Создадим два новых стиля, которые будут наследовать стиль Text:
styles.xml
<resources>
<!--Остальной код выше не изменился-->
<stylename="Text">
<itemname="android:layout_width">wrap_content</item>
<itemname="android:layout_height">wrap_content</item>
<itemname="android:layout_margin">10dp</item>
<itemname="android:textSize">25sp</item>
</style>
<stylename="DarkBlueText"parent="Text">
<itemname="android:textColor">@color/text_dark</item>
</style>
<stylename="DarkGreenText"parent="Text">
<itemname="android:textColor">@color/colorPrimaryDark</item>
</style>
</resources>
Также есть возможность наследовать стили, используя символа . (точка). Изменим стили :
styles.xml
<resources>
<!--Остальной код выше не изменился-->
<stylename="Text.DarkBlue">
<itemname="android:textColor">@color/text_dark</item>
</style>
<stylename="Text.DarkGreen">
<itemname="android:textColor">@color/colorPrimaryDark</item>
</style>
</resources>
При таком подходе родительский стиль пишется вначале, после него – символ . (точка), а потом название дочернего стиля. Принципиальной разницы между этими двумя подходами наследования нет. Этот вариант выглядит более читабельным, когда названия стилей короткие.
Но у такого подхода есть ограничение: мы не можем его применять когда наследуемся от каких-то Android стилей, как например стиль AppTheme. В таким случаях мы обязаны использовать ключевое слово parent:
styles.xml
<!-- Base application theme. -->
<stylename="AppTheme"parent="Theme.AppCompat.Light.DarkActionBar"/>
Переопределение атрибутов родительского стиля
Аналогично с наследованием классов в Java, мы можем переопределить атрибуты родительского стиля. Для примера переопределим атрибут textSize:
styles.xml
<resources>
<!--Остальной код выше не изменился-->
<stylename="Text.DarkGreen"parent="Text">
<itemname="android:textSize">35sp</item>
</style>
</resources>
Папка drawable. Работа с картинками
Чтобы добавить картинку в приложение в первую очередь необходимо скачать картинку и добавить её в папку drawable. Давайте скачаем эту картинку для примера и добавим в папку drawable:
Доступ к картинке из XML кода
Также, как и к строкам, цветам, мы можем обращаться к картинкам из XML кода. Для этого необходимо указать ссылку на картинку в layout файле, используя элемент ImageView и атрибут android:src.
Вначале мы достаём из ресурсов картинку с помощью getResources().getDrawable(R.drawable.android_jetpack). Картинка в Java коде имеет тип Drawable. Далее, вызывая методimageView.setImageDrawable(), мы устанавливаем картинку вImageView. Можете запустить приложение и убедиться, что результат не изменился.
В Android системе существует намного больше различных ресурсов, таких как font, dimens, arrays. На первых этапах они вам не понадобятся. Но как только возникнет необходимость, вы сможете найти нужный вам ресурс и документацию по нему на официальном сайте.
Заключение
Ресурсы облегчают жизнь Android разработчика. Поэтому всегда используйте их при возможности. Вы потратите чуть больше времени сейчас на их создание, зато сэкономите кучу времени при добавлении новой функциональности в приложение. Сегодня вы познакомились с простейшей локализацией, использованием стилей, цветов и увидели реальную пользу от применения ресурсов.
Сайт использует cookie-файлы для того, чтобы вам было удобнее им пользоваться. Для
продолжения работы с сайтом, вам необходимо принять использование cookie-файлов.
Структура урока:
Ресурсы
В Android системе почти всё, что не является Java кодом, является ресурсами. Ресурсы используются для определения цветов, изображений, макетов, строковых значений и т.д. Вы можете указывать значения в файлах ресурсов, а потом ссылаться на них в Java коде вашего приложения.
Все ресурсы находятся в папке
res
. Посмотрим, какие по умолчанию есть папки, файлы в каталогеres
.drawable
– хранит в себе картинки, другие графические файлы.layout
– хранит все макеты приложения.mipmap
– хранит лого приложения, которое отображается в меню приложений.values
– хранит в себе разные ресурсы, такие как цвета, строки, стили, размеры.Далее нам необходимо в верхнем левом углу поменять отображение проекта с
Android
наProject
. Это позволит нам увидеть все папки, которые реально созданы в нашем проекте. Изначально мы не делали этого, чтобы не пугать вас :)Ресурсы из папки res/values
Нажмём на папку
values
, посмотрим, что в ней находится:colors.xml
– содержит в себе все цвета.strings.xml
– хранит все строковые ресурсы.styles.xml
– хранит стили приложения.Хранение таких данных в отдельных ресурсах дает нам гибкость и удобство при работе с проектом. Мы рассмотрим преимущества использования ресурсов на примере локализации – поддержки нескольких языков в приложении.
Файл string.xml. Локализация
Мы будем поддерживать два языка в нашем приложении: английский и русский. Для локализации приложения используют файл
strings.xml
. Туда помещается весь текст приложения, который должен быть подвержен локализации. Чтобы добавить поддержку ещё одного языка, надо создать папку с именемvalues-language
. Т.к. мы поддерживаем русский язык, то создадим папкуvalues-ru
. Для этого нажмём правой кнопкой на папкуres
и выберем пунктNew -> Android resource directory
:Directory name
–values-ru
Resource type
–values
Source set
–main
Вот как это должно выглядеть:
После этого видим, что создалась папка
values-ru
. Отлично, создадим новый файлstrings.xml
. Для этого нажимаем правой кнопкой по папкеvalues-ru
, выбираемNew -> Values resource file
:Затем появится окно, в котором необходимо ввести имя файла. Вводим
strings
. Теперь всё, что нам надо сделать – это добавлять ресурсы в эту папку с таким же именем, но значения мы будем писать на русском языке. Система автоматически будет брать значения из этого файла, если у пользователя на устройстве установлен русский язык. Для начала давайте посмотрим как выглядит обычный строковый ресурс:sample_resource.xml
У каждого строкового ресурса есть имя, по которому в дальнейшем будет идти обращение к нему, а также его значение. На самом деле так выглядят не только строковые ресурсы, а все ресурсы приложения:
resource_format.xml
Просто вместо типа ресурса
string
используются другие необходимые значения (color
,dimen
и т.д.). Теперь проверим, что это всё действительно работает. В файлеvalues/strings.xml
по умолчанию при создании проекта есть строкаapp_name
:values/strings.xml
Теперь добавим эту же строку, но на русском языке в файл
values-ru/strings.xml
:values-ru/strings.xml
Видим, что название ресурса
app_name
совпадает в двух папках. А вот значения мы можем указывать для каждого языка свои.Доступ к ресурсам из XML
Теперь после создания строкового ресурса нам необходимо использовать его в
layout
файле. Ссылка на наш ресурс будет выглядеть так:@string/app_name
. Но сейчас остановимся на минуту и разберём общий синтаксис при ссылке на файл ресурса из XML:<имя_пакета>
– имя пакета, в котором находится ресурс. Чаще всего его не будет, т.к. мы берём ресурсы из своего приложения. Если бы мы хотели взять строку изandroid
библиотеки, то обращались бы@android:string
.<тип_ресурса>
– тип ресурса, к которому мы обращаемся. В данном случае –string
. Обратите внимание, что название отличается от названия файлаstrings
– используется единственное число.<имя_ресурса>
– название ресурса.Теперь, когда мы научились обращаться к ресурсам, давайте в файле
activity_main.xml
уTextView
заменим текст на только что созданный строковый ресурс.activity_main.xml
Запустим приложение и убедимся, что локализация действительно работает. После запуска приложения на эмуляторе, видим, что вывелась строка
Resources
, т.к. на эмуляторе стоит английский язык.Давайте добавим русский язык и сделаем его основным. Для этого необходимо зайти в настройки системы и выбрать: System -> Languages & input -> Languages -> Русский. После добавления ставим русский язык первым:
Можем открыть приложение на эмуляторе или запустить его заново. Результат выглядит так:
Отображается надпись
Ресурсы
. Вот такое простое и элегантное решение предоставляет нам система для добавления поддержки новых языков. Стоит отметить, что помимо ручного заполнения файлов с ресурсами, существует возможность делать это через специальный редактор. Чтобы в него попасть необходимо, открыв файл со строковыми ресурсами (любого языка), в правом верхнем углу нажать кнопку «Open editor» (рус. Открыть редактор). Удобно использовать редактор, чтобы убедиться, что вы перевели все строки в приложении:Вы можете заметить, что строка может быть нелокализируемой (поле
untranslatable
). Примером могут быть технические термины, которые не переводят на другие языки:IMAP
,NFC
,GPS
. Для таких строк в файлеstrings.xml
необходимо установить атрибутtranslatable="false"
. В файлах для остальных языков не надо дублировать эти строки.values/string.xml
Доступ к ресурсам из Java кода
Также к ресурсам можно получить доступ из Java кода. Посмотрим на синтаксис.
Видим, что он очень похож на синтаксис доступа к ресурсу из XML. Параметры
имя_пакета
,тип_ресурса
,имя_ресурса
являются идентичными.Доступ к нашему ресурсу можно получить так:
R.string.app_name
.Разберём на примере, как установить текстовый ресурс в
TextView
из Java кода:activity_main.xml
Обратите внимание, что атрибут
text
мы не указали в XML файле.MainActivity.java
Вначале мы связываем
TextView
из XML файла с Java кодом с помощьюfindViewById(R.id.text)
. Потом получаем строку, используяgetResources().getString(R.string.app_name)
. После этого устанавливаем строку вTextView
с помощьюsetText(appName)
. Запустите приложение и убедитесь, что логика локализации не изменилась.Зачем работать с ресурс файлами из Java кода, если можно из XML?
Бывают ситуации, когда вы заранее не можете знать, какой ресурс вы хотите использовать. Например, если в соц. сети человек уже прочитал сообщение, то вы хотите отобразить “Прочитано”, в другом случае – “Отправлено”. Именно в таких случаях необходимо работать с ресурсами из Java кода.
Файл colors.xml
Файл
colors.xml
хранит в себе цвета приложения. Это удобно, потому что вы храните (изменяете при необходимости) цвет в одном месте. По умолчанию создаются цвета, которые используются в нашем приложении. Добавим ещё два цвета:colors.xml
Используем эти цвета в
layout
файле, обращаясь к ним@color/background_light
,@color/text_dark
:strings.xml
activity_main.xml
Теперь представьте, что дизайнер сказал вам изменить цвет текста с чёрного на тёмно синий, а фоновый цвет – с серого на тускло жёлтый. Изменяем только значения в
colors.xml
:colors.xml
Результат:
Доступ из Java кода осуществляется аналогично, как и со строковыми ресурсами. Разберём на примере:
activity_main.xml
MainActivity.java
С помощью
getResources().getColor()
получаем цвет, а используяsetTextColor()
,setBackgroundColor()
устанавливаем цвета. В реальной жизни с этим часто приходится работать, когда в зависимости от статуса заказа товара в интернет-магазине изменяется фоновый цвет кнопки или контейнера.Результат:
Файл styles.xml. Стили
Файл
styles.xml
нужен для того, чтобы объединять повторяющиеся атрибуты элементов в стили. Давайте откроем файлstyles.xml
:styles.xml
По умолчанию в приложении создаётся стиль
AppTheme
, который задаёт основные цвета нашего приложения. Синтаксис создания стиля довольно простой:Давайте на практике рассмотрим использование стилей. У нас есть такой
layout
, в котором у двухTextView
повторяется множество атрибутов:activity_main.xml
Мы можем вынести все эти атрибуты в новый стиль:
styles.xml
И после этого используем этот стиль в файле
activity_main.xml
, устанавливая атрибутstyle
, передавая ему ссылку на стиль@style/Text
:activity_main.xml
Теперь, когда мы захотим поменять размер текста или изменить, добавить любой другой атрибут, то поменяем его в стиле
Text
. Стили позволяют избежать дублирование кода.Наследование стилей
Наследование с помощью слова parent
Теперь давайте усложним задачу. Пусть первый текст будет тёмно синим, а второй – тёмно зелёным. Мы можем воспользоваться наследованием стилей. Создадим два новых стиля, которые будут наследовать стиль
Text
:styles.xml
И применим эти стили в файле
activity_main.xml
:activity_main.xml
Результат:
Наследование с помощью символа . (точка)
Также есть возможность наследовать стили, используя символа
.
(точка). Изменим стили :styles.xml
При таком подходе родительский стиль пишется вначале, после него – символ
.
(точка), а потом название дочернего стиля. Принципиальной разницы между этими двумя подходами наследования нет. Этот вариант выглядит более читабельным, когда названия стилей короткие.Но у такого подхода есть ограничение: мы не можем его применять когда наследуемся от каких-то Android стилей, как например стиль
AppTheme
. В таким случаях мы обязаны использовать ключевое словоparent
:styles.xml
Переопределение атрибутов родительского стиля
Аналогично с наследованием классов в Java, мы можем переопределить атрибуты родительского стиля. Для примера переопределим атрибут
textSize
:styles.xml
Папка drawable. Работа с картинками
Чтобы добавить картинку в приложение в первую очередь необходимо скачать картинку и добавить её в папку
drawable
. Давайте скачаем эту картинку для примера и добавим в папкуdrawable
:Доступ к картинке из XML кода
Также, как и к строкам, цветам, мы можем обращаться к картинкам из XML кода. Для этого необходимо указать ссылку на картинку в
layout
файле, используя элементImageView
и атрибутandroid:src
.activity_main.xml
Результат:
Доступ к картинке из Java кода
Также мы можем отобразить картинку, используя Java код. Выглядит это так:
activity_main.xml
MainActivity.java
Вначале мы достаём из ресурсов картинку с помощью
getResources().getDrawable(R.drawable.android_jetpack)
. Картинка в Java коде имеет типDrawable
. Далее, вызывая методimageView.setImageDrawable()
, мы устанавливаем картинку вImageView
. Можете запустить приложение и убедиться, что результат не изменился.Заключение
Ресурсы облегчают жизнь Android разработчика. Поэтому всегда используйте их при возможности. Вы потратите чуть больше времени сейчас на их создание, зато сэкономите кучу времени при добавлении новой функциональности в приложение. Сегодня вы познакомились с простейшей локализацией, использованием стилей, цветов и увидели реальную пользу от применения ресурсов.
Полезные материалы: