Использование ресурсов.

Урок 9 — Использование ресурсов.

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

В ресурсах хранятся следующие вещи:

  • Файлы верстки
  • Строки, массивы строк
  • Цвета
  • Размеры
  • Стили
  • Анимации
  • Меню
  • И несколько других типов данных

На самом деле, вы уже работали с ресурсами, когда меняли верстку нашего пока что единственного экрана. Возможно, вы заметили, что Android Studio показывает предупреждения, например, для атрибута android:text у TextView:

Hardcoded string "Hello", should use @string resource

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

Класс R

Вы уже могли заметить, что мы используем некий таинственный класс R при обращении, например, к View по идентификатору. Класс R (от слова Resources) генерируется автоматически при сборке проекта (Android Studio генерирует его динамически — а раньше нужно было пересобирать проект). При помощи него мы можем обращаться к ресурсам (идентификатор View — тоже ресурс). Если вы его откроете, то увидите что-то вроде этого:

public final class R {
  public static final class anim {
    public static final int abc_fade_in=0x7f010000;
    public static final int abc_fade_out=0x7f010001;
    public static final int abc_grow_fade_in_from_bottom=0x7f010002;
    public static final int abc_popup_enter=0x7f010003;
    public static final int abc_popup_exit=0x7f010004;
    public static final int abc_shrink_fade_out_from_bottom=0x7f010005;
    public static final int abc_slide_in_bottom=0x7f010006;
    public static final int abc_slide_in_top=0x7f010007;
    public static final int abc_slide_out_bottom=0x7f010008;
    public static final int abc_slide_out_top=0x7f010009;
    public static final int tooltip_enter=0x7f01000a;
    public static final int tooltip_exit=0x7f01000b;
  }
  public static final class attr {
  //
  }
}

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

Строки

Начнем с самого часто используемого: со строк. Строковые ресурсы хранятся в файле res/values/strings.xml. На самом деле, можно использовать несколько файлов, или переименовать файл — это не важно, главное, чтобы строки были внутри директории res/values.

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

<resources>
    <string name="app_name">Lessons</string>
</resources>

Новые строки добавляются внутри тега <resources/>. У строки есть атрибут name, в котором нужно обязательно указать уникальный идентификатор строки. Правила те же, что и для идентификаторов у View: латинские символы, цифры и знак подчеркивание, имя должно начинаться с буквы.

Внутри тега указываем, собственно, строку. Давайте перенесем значение атрибута android:text нашего TextView в строковые ресурсы. Добавьте новую строку в файл strings.xml, чтобы он выглядел вот так:

<resources>
    <string name="app_name">Lessons</string>

    <string name="hello_text">Hello</string>
</resources>

Теперь зададим эту строку в самом TextView (в файле activity_main.xml). Для того, чтобы сослаться на строковый ресурс, нужно использовать следующий синтаксис: @string/name, где name — имя строки в strings.xml. Таким образом, TextView теперь выглядит вот так:

<TextView
        android:id="@+id/hello_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_text"
        android:textSize="28sp" />

Форматирование строк

В Java-коде мы устанавливаем текст в TextView:

textView.setText("Hi, " + name);

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

<string name="name_text_format">Hi, %1$s</string>

В данном случае %1$s будет заменен на текст. %1 — порядковый номер (если мы будем форматировать 2 аргумента, то второй будет начинаться с %2), а $s — формат. У нас это строка, если мы будем использовать число — то это будет $d, если число с плавающей точкой — то $f (можно также указать точность, например $.2f — 2 знака после запятой).

Итак, добавьте эту строку в strings.xml, и замените Java-код на следующий:

textView.setText(getString(R.string.name_text_format, name));

Метод getString() получает строку из ресурсов, и форматирует её, используя переданные аргументы. Если строку не нужно форматировать, то передается только идентификатор строки.

Запустите приложение, чтобы убедиться, что все работает.

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

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

Давайте переведем текст на русский язык. Нажмите правой кнопкой на директорию res, во всплывающем окне выберите New, затем Android resource file:

Создание нового файла ресурсов в Android Studio
Создание нового файла ресурсов в Android Studio

В появившемся окне в поле File name введите "strings". Resource type — "values", Source set — "main", Directory name — "values":

Создание файла ресурсов со строками
Создание файла ресурсов со строками

Снизу слева вы можете увидеть различные варианты, по которым мы можем дифференцировать конфигурацию пользовательского устройства. На данный момент нам нужен пункт Locale. Выберите его и нажмите на кнопку >> чуть правее. Появятся два дополнительных списка, Language и Specific Region Only. В списке Language выберите ru: Russian:

Выбор конфигурации для файла ресурсов
Выбор конфигурации для файла ресурсов

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

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

После того, как вы нажмете на кнопку ОК, создастся новый файл:

Созданный файл строковых ресурсов
Созданный файл строковых ресурсов

Как видите, он создался в директории res/values-ru, то есть values с русской локалью.

Файл пока почти что пуст: по умолчанию существующие строки добавляться в него не будут. Есть два варианта добавления строк для перевода:

  1. Добавить строку вручную.
  2. Воспользоваться встроенным редактором переводов.

В первом случае просто скопируйте строку из оригинального файла и вставьте в новый, после чего переведите. Например, я скопирую первые две строки — имя приложения и приветственный текст. Теперь мой файл выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Уроки</string>

    <string name="hello_text">Привет</string>
</resources>

Второй вариант в теории должен быть удобнее, на практике же его реализация на данный момент оставляет желать лучшего. Откройте любой strings.xml. Вверху справа вы увидите кнопку Open editor:

Кнопка "Open Editor"
Кнопка "Open Editor"

Нажмите на нее. Откроется редактор строк:

Редактор строк в Android Studio
Редактор строк в Android Studio

Непереведённые строки подсвечиваются красным. Давайте переведем. Для этого поставьте курсор в соответствующую ячейку и введите текст. Получится вот так:

Редактор строк в Android Studio
Редактор строк в Android Studio

А русский файл строк теперь выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Уроки</string>

    <string name="hello_text">Привет</string>
    <string name="name_text_format">Привет, %1$s</string>
</resources>

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

Точно так же локализация работает и для других ресурсов: создайте директорию в ресурсах (либо методом, показанным выше, либо вручную) с соответствующим названием и скопируйте туда нужные локализованные ресурсы.

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

Цвета

Цвета хранятся в директории res/values в файле colors.xml. Откройте этот файл:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>

Как видите, в нем уже есть три цвета. Эти цвета сгенерировала Android Studio при создании проекта.

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


Продолжение доступно на платных тарифах

Это недорого — всего от 440 ₽ в месяц!


ВЫБРАТЬ ТАРИФ


Продолжение доступно после регистрации

Все уроки на сайте доступны абсолютно бесплатно после регистрации.

Регистрация займёт меньше минуты ;)