Recursos no Compose

O Jetpack Compose pode acessar os recursos definidos no seu projeto Android. Este documento explica algumas das APIs que o Compose oferece para fazer isso.

Recursos são os arquivos complementares e o conteúdo estático usado pelo seu código, como bitmaps, definições de layout, strings da interface do usuário, instruções de animação, entre outras coisas. Se você não está familiarizado com os recursos no Android, consulte o guia sobre visão geral de recursos de apps.

Strings

O tipo mais comum de recurso são as strings. Use a API stringResource para recuperar uma string definida estaticamente nos recursos XML.

// In the res/values/strings.xml file
// <string name="compose">Jetpack Compose</string>

// In your Compose code
Text(
    text = stringResource(R.string.compose)
)

stringResource também funciona ao definir o formato de posicionamento.

// In the res/values/strings.xml file
// <string name="congratulate">Happy %1$s %2$d</string>

// In your Compose code
Text(
    text = stringResource(R.string.congratulate, "New Year", 2021)
)

Plurais de strings (recurso experimental)

Use a API pluralStringResource para carregar um plural com determinada quantidade.

// In the res/strings.xml file
// <plurals name="runtime_format">
//    <item quantity="one">%1$d minute</item>
//    <item quantity="other">%1$d minutes</item>
// </plurals>

// In your Compose code
Text(
    text = pluralStringResource(
        R.plurals.runtime_format,
        quantity,
        quantity
    )
)

Ao usar o método pluralStringResource, você precisa passar a contagem duas vezes se a string contém formatação com um número. Por exemplo, para a string %1$d minutes, o primeiro parâmetro de contagem seleciona o plural adequado, e o segundo parâmetro de contagem é inserido no marcador de posição %1$d. Se as strings de plural não incluírem formatação de string, não vai ser necessário transmitir o terceiro parâmetro para pluralStringResource.

Para ver mais informações sobre plurais, consulte a documentação da string de quantidade.

Dimensões

Da mesma forma, use a API dimensionResource para ver as dimensões de um arquivo XML de recurso.

// In the res/values/dimens.xml file
// <dimen name="padding_small">8dp</dimen>

// In your Compose code
val smallPadding = dimensionResource(R.dimen.padding_small)
Text(
    text = "...",
    modifier = Modifier.padding(smallPadding)
)

Cores

Se você estiver adotando o Compose gradualmente no app, use a API colorResource para receber cores de um arquivo XML de recursos.

// In the res/colors.xml file
// <color name="purple_200">#FFBB86FC</color>

// In your Compose code
Divider(color = colorResource(R.color.purple_200))

colorResource funciona da forma esperada com cores estáticas, mas nivela os recursos da lista de estados de cores.

Recursos de vetor e recursos de imagem

Use a API painterResource para carregar drawables vetoriais ou formatos de recursos rasterizados, como PNGs. Não é necessário saber o tipo de drawable, basta usar painterResource em Image que podem ser compostas ou modificadores paint.

// Files in res/drawable folders. For example:
// - res/drawable-nodpi/ic_logo.xml
// - res/drawable-xxhdpi/ic_logo.png

// In your Compose code
Icon(
    painter = painterResource(id = R.drawable.ic_logo),
    contentDescription = null // decorative element
)

painterResource decodifica e analisa o conteúdo do recurso na linha de execução principal.

Drawables vetoriais animados

Use a API AnimatedImageVector.animatedVectorResource para carregar um XML de drawables vetoriais animados. O método retorna uma instância de AnimatedImageVector. Se quiser mostrar a imagem animada, use o método rememberAnimatedVectorPainter para criar um Painter que possa ser usado nos elementos Image e Icon. O parâmetro booleano atEnd do método rememberAnimatedVectorPainter indica se a imagem deve ser desenhada no final de todas as animações. Se usado com um estado mutável, trocar esse valor acionará a animação correspondente.

// Files in res/drawable folders. For example:
// - res/drawable/ic_hourglass_animated.xml

// In your Compose code
val image =
    AnimatedImageVector.animatedVectorResource(R.drawable.ic_hourglass_animated)
val atEnd by remember { mutableStateOf(false) }
Icon(
    painter = rememberAnimatedVectorPainter(image, atEnd),
    contentDescription = null // decorative element
)

Ícones

O Jetpack Compose inclui o objeto Icons, que é o ponto de entrada para usar ícones do Material Design no Compose (link em inglês). Existem cinco temas de ícones diferentes Preenchido, Contornado, Arredondado, TwoTone e Pontiagudo. Cada tema contém os mesmos ícones, mas com um estilo visual diferente. Em geral, um tema é escolhido e usado em todo o app para manter a consistência.

Para desenhar um ícone, você pode usar o Icon que pode ser composto, que aplica tonalidade e fornece um tamanho do layout que corresponda ao ícone.

Icon(Icons.Rounded.Menu, contentDescription = "Localized description")

Alguns dos ícones mais usados estão disponíveis como parte da dependência androidx.compose.material. Para usar qualquer um dos outros ícones do Material Design, adicione a dependência material-icons-extended ao arquivo build.gradle.

dependencies {
  def composeBom = platform('androidx.compose:compose-bom:2024.03.00')
  implementation composeBom

  implementation 'androidx.compose.material:material-icons-extended'
}

Fontes

Para usar fontes no Compose, faça o download e agrupe os arquivos de fontes diretamente nos APKs, colocando-os na pasta res/font.

Carregue cada fonte usando a API Font e crie uma FontFamily, para usar em instâncias de TextStyle e criar uma Typography própria. Veja a seguir o código retirado do exemplo do Compose Crane e o respectivo arquivo Typography.kt (em inglês).

// Define and load the fonts of the app
private val light = Font(R.font.raleway_light, FontWeight.W300)
private val regular = Font(R.font.raleway_regular, FontWeight.W400)
private val medium = Font(R.font.raleway_medium, FontWeight.W500)
private val semibold = Font(R.font.raleway_semibold, FontWeight.W600)

// Create a font family to use in TextStyles
private val craneFontFamily = FontFamily(light, regular, medium, semibold)

// Use the font family to define a custom typography
val craneTypography = Typography(
    titleLarge = TextStyle(
        fontFamily = craneFontFamily
    ) /* ... */
)

// Pass the typography to a MaterialTheme that will create a theme using
// that typography in the part of the UI hierarchy where this theme is used
@Composable
fun CraneTheme(content: @Composable () -> Unit) {
    MaterialTheme(typography = craneTypography) {
        content()
    }
}

Para usar fontes para download no Compose, consulte a página Fontes para download.

Para saber mais sobre tipografia, consulte a documentação Temas no Compose.