Ресурсы в Jetpack Compose

Ресурсы строк

Последнее обновление: 09.04.2024

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

Одним из наиболее применяемых типов ресурсов являются ресурсы строк. Они используются при выведении названия приложения, различного текста, например, текста кнопок и т.д. Например, нам нужно вывести в различных местах приложения один и тот же текст. Вместо того, чтобы по несколько раз определять его в коде Kotlin, мы можем определить его один раз в виде строкового ресурса и использовать в любом месте приложения.

По умолчанию строковые ресурсы хранятся в проекте в каталоге res/values. При создании проекта в этот каталог по умолчанию добавляется файл строковых ресурсов strings.xml.

Ресурсы строк в Jetpack Compose и Android

Если мы откроем файл, то мы найдем в нем строки наподобие следующих:

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

Каждый отдельный строковый ресурс определяется с помощью элемента string, а его атрибут name содержит название ресурса. Так, в самом простом виде этот файл определяет один ресурс "app_name", который устанавливает название приложения и который в моем случае имеет значение "helloapp" (по умолчанию значение этого ресурса соответствует названию проекта). Но естественно мы можем определить любые строковые ресурсы.

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

R.string.название_ресурса

Например, для обращения к определенному по умолчанию строковому ресурсу app_name применяется идентификатор

R.string.app_name

Чтобы получить строковый ресурс в коде Kotlin, применяется встроенная функция androidx.compose.ui.res.stringResource(), в которую передается идентификатор ресурса и которая возвращает строку в виде объекта String. Например, получим в коде ресурс app_name:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text(
                text = stringResource(R.string.app_name),
                fontSize = 28.sp
            )
        }
    }
}

В данном случае параметру text компонента Text передается строка из строкового ресурса app_name:

Функция stringResource в Kotlin и Jetpack Compose и Android

Подобным образом при необходимоси мы можем определять и свои ресурсы. Например, изменим файл res/values/strings.xml следующим образом:

<resources>
    <string name="app_name">helloapp</string>
    <string name="message">Hello METANIT.COM</string>
</resources>

Здесь добавлен строковый ресурс "message", который имеет значение "Hello METANIT.COM"

Используем этот строковый ресурс в коде:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text(
                text = stringResource(R.string.message),
                fontSize = 28.sp
            )
        }
    }
}
Получение ресурса строк в stringResource в Kotlin и Jetpack Compose и Android

Добавление файла ресурсов строк

Хотя по умолчанию для ресурсов строк применяется файл strings.xml, но можно добавлять дополнительные файлы ресурсов в каталог проекта res/values. При этом достаточно соблюдать структуру файла: он должен иметь корневой узел <resources> и иметь один или несколько элементов <string>.

Так, нажмем на папку res/values правой кнопкой мыши и в появившемся списке выберем пункт New -> Value Resource File:

Добавление ресурса строк в Jetpack Compose и Android Studio

После этого нам будет предложено определить для файла имя:

Add string resource in Jetpack Compose and Android Studio

Назовем, к примеру, headers.xml (название файла произвольное), а для всех остальных полей оставим значения по умолчанию. И в папку res/values будет добавлен новый файл headers.xml. Определим в нем пару ресурсов:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="welcome">Добро пожаловать</string>
    <string name="click_button">Отправить</string>
</resources>

И после этого мы также сможем использовать эти ресурсы в коде Kotlin, например:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Column{
                Text(
                    text = stringResource(R.string.welcome),
                    fontSize = 28.sp
                )
                Button({}){
                    Text(
                        text = stringResource(R.string.click_button),
                        fontSize = 22.sp
                    )
                }
            }
        }
    }
}

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

Функция stringResource() позволяет применять к ресурсам строк форматирование. Преимуществом форматирования является то, что мы можем определить общий щаблон и затем подставлять в него необходимые значения. Например, изменим файл strings.xml:

<resources>
    <string name="app_name">helloapp</string>
    <string name="user_data">Имя: %1$s. Возраст: %2$d. Компания: %3$s</string>
</resources>

Здесь ресурс user_data представляет строку с форматированием. Так, она содержит такие символы как %1$s, %2$d и %3$ds. Что они означают? %1$s указывает, что это первый аргумент, а символ "s" говорит, что этот аргумент представляет строку. %2$d представляет второй аргумент, а символ "d" в конце указывает, что это будет целое число. Аналогично %3$s указывает, что это третий аргумент, который представляет строку.

Получим ресурс в коде Kotlin:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Column{
                Text(
                    text = stringResource(R.string.user_data, "Tom", 37, "JetBrains"),
                    fontSize = 28.sp
                )
                Text(
                    text = stringResource(R.string.user_data, "Bob", 41, "Google"),
                    fontSize = 28.sp
                )
            }
        }
    }
}
Форматирование строк в функции stringResource в Kotlin в Jetpack Compose

Вызов функции stringResource(R.string.user_data, "Tom", 37, "JetBrains") получает ресурс "user_data" и в качестве последующих параметров передает в строку вставляемые значения. Так, вместо первого аргумента-строки в user_data вставляется второй аргумент функции - строка "Tom", вместо второго аргумента-числа в user_data вставляется число 37, а вместо третьего аргумента в user_data передается строка "JetBrains".

Ресурсы Plurals

Ресурсы Plurals представляют еще один вид набора строк, в которым применяется форматирование. Он предназначен для описания количества элементов. Для чего это надо? К примеру, возьмем существительное: нередко оно изменяет окончание в зависимости от числительного, которое с ним употребляется: 1 цветок, 2 цветка, 7 цветков. Для подобных случаев и используется ресурс plurals.

Посмотрим на примере. Добавим в папку res/values новый ресурс flowers.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <plurals name="flowers">
        <item quantity="one">%d цветок</item>
        <item quantity="few">%d цветка</item>
        <item quantity="many">%d цветков</item>
    </plurals>
</resources>

Для задания ресурса используется элемент <plurals>. Его атрибут name хранит название ресурса.

Сами наборы строк вводятся дочерними элементами <item>. Этот элемент имеет атрибут quantity, который имеет значение, указывающее, когда эта строка используется. Данный атрибут может принимать следующие значения:

  • zero: строка для количества в размере 0

  • one: строка для количества в размере 1 (для русского языка - для задания всех количеств, оканчивающихся на 1, кроме 11)

  • two: строка для количества в размере 2

  • few: строка для небольшого количества

  • many: строка для больших количеств

  • other: все остальные случаи

Причем в данном случае многое зависит от конкретного языка. А система сама позволяет определить, какое значение брать для того или иного числа.

Получим и используем этот ресурс в коде Kotlin:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp
import androidx.compose.ui.platform.LocalContext

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val resources = LocalContext.current.resources
            Column{
                Text(
                    text = resources.getQuantityString(R.plurals.flowers, 21, 21),
                    fontSize = 28.sp
                )
                Text(
                    text = resources.getQuantityString(R.plurals.flowers, 7, 7),
                    fontSize = 28.sp
                )
            }
        }
    }
}

На данный момент Jetpack Compose не поддерживает напрямую получение подобных ресурсов. Поэтому для их извлечения вначале необходимо получить текущий контекст через свойство LocalContext.current и затем обратиться к его свойству resource, которое представляет класс Resources и ассоциирован со всеми ресурсами приложения.

Далее с помощью метода getQuantityString класса Resources получаем значение ресурса. Первым параметром передаем идентификатор ресурса. Вторым параметром идет значение. для которого нужно найти нужную строку. Третий параметр представляет собой значение, которое будет вставляться на место плейсхолдера %d. То есть мы получаем строку для числа 21.

Определение ресурса plurals в Jetpack Compose и Kotlin в Android

Массивы строк

Еще один тип ресурсов представляют массивы строк в виде элемента string-array. Его можно использовать, когда надо определить какой-нибудь набор строк. Например, добавим в папку res/values новый файл, который назовем languages.xml:

ресурсы stringarray в Jetpack Compose на Kotlin на Android

В этом файле определим следующее содержимое:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="languages">
        <item>Kotlin</item>
        <item>Java</item>
        <item>JavaScript</item>
        <item>Python</item>
        <item>C++</item>
    </string-array>
</resources>

Массив строк определяется с помощью элемента <string-array name="languages">. В данном случае этот ресурс называется "languages". Каждая отдельная строка этотго массива представлена элементом <item>. И в данном случае в массиве определено 5 элементов.

Теперь получим этот массив в приложении на Kotlin:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val items = resources.getStringArray(R.array.languages)
        setContent {
            Column{
                for(item in items){
                    Text(item, Modifier.padding(8.dp), fontSize = 28.sp)
                }
            }
        }
    }
}

Для получения массива применяется метод getStringArray(), в который передается имя ресурса:

val items = resources.getStringArray(R.array.languages)

Возвращаемый объект представляет массив типа Array<String>, который, например, можно перебрать и вывести в виде компонентов Text в приложении:

ресурсы stringarray и список строк в Jetpack Compose на Kotlin на Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850