Recursos no Compose

O Jetpack Compose pode acessar os recursos definidos em 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 string

O Compose ainda não oferece um método direto para recuperar plurais de String. No entanto, é possível usar a abordagem tradicional com o método getQuantityString da classe Resources. Para acessar Resources a partir do Context atual, use o local de composição LocalContext. Leia mais sobre os locais de composição na documentação sobre interoperabilidade.

// 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
val resources = LocalContext.current.resources

Text(
    text = resources.getQuantityString(
        R.plurals.runtime_format, quantity, quantity
    )
)

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="colorGrey">#757575</color>

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

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 animatedVectorResource para carregar um XML de drawable vetorial animado. O método retorna uma instância AnimatedImageVector. Para exibir a imagem animada, use o método painterFor para criar um Painter que possa ser usado nas funções Image e Icon. O parâmetro booleano atEnd do método painterFor indica se a imagem deve ser desenhada no final de todas as animações. Se usado com um estado mutável, mudanças nesse valor acionarão a animação correspondente.

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

// In your Compose code
val image = animatedVectorResource(id = R.drawable.animated_vector)
val atEnd by remember { mutableStateOf(false) }
Icon(
    painter = image.painterFor(atEnd = 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.

import androidx.compose.material.Icon

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 {
  ...
  implementation "androidx.compose.material:material-icons-extended:$compose_version"
}

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 que você possa usá-las em instâncias de TextStyle para criar uma Typography própria. Veja o código a seguir retirado da amostra do Compose Crane e do arquivo Typography.kt (links 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(
    defaultFontFamily = 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 saber mais sobre tipografia, consulte a documentação Temas no Compose.