Compose 中的资源

Jetpack Compose 可以访问您的 Android 项目中定义的资源。本文将介绍 Compose 为此提供的一些 API。

资源是指代码使用的附加文件和静态内容,例如位图、布局定义、界面字符串、动画说明等。如果您不熟悉 Android 中的资源,请参阅应用资源概览指南

字符串

最常见的资源类型就是字符串。使用 stringResource API 检索在 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 也支持位置格式设置。

// 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)
)

字符串复数

Compose 目前还未提供直接检索 String 复数的方法。不过,您可以结合使用传统方法与 Resources 类的 getQuantityString 方法。如需从当前 Context 访问 Resources,请使用 LocalContext CompositionLocal。如需详细了解 CompositionLocal,请参阅互操作性文档。

// 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
    )
)

尺寸

同样,使用 dimensionResource API 从资源 XML 文件获取尺寸。

// 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)
)

颜色

如果您在应用中增量采用 Compose,请使用 colorResource API 从资源 XML 文件中获取颜色。

// In the res/colors.xml file
// <color name="colorGrey">#757575</color>

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

colorResource 可以按预期处理静态颜色,但它会拼合颜色状态列表资源

矢量资源和图像资源

使用 painterResource API 加载矢量可绘制对象或光栅化资源格式(例如 PNG)。您无需了解可绘制对象的类型,只需在 Image 可组合项或 paint 修饰符中使用 painterResource

// 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 可在主线程中解码并解析资源的内容。

带动画的矢量可绘制对象

使用 animatedVectorResource API 加载带动画的矢量可绘制对象 XML。该方法会返回一个 AnimatedImageVector 实例。为显示带动画的图像,请使用 painterFor 方法创建可在 ImageIcon 可组合项中使用的 PainterpainterFor 方法的布尔值 atEnd 参数指示是否应在所有动画结束时绘制图像。如果与可变状态结合使用,更改此值将触发相应的动画。

// 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
)

图标

Jetpack Compose 附带 Icons 对象,该对象是在 Compose 中使用 Material 图标的入口点。共有以下五种不同的图标主题:FilledOutlinedRoundedTwoToneSharp。每个主题包含相同的图标,但视觉风格不同。通常,您应该选择一种主题,并在整个应用中保持使用这一主题,从而确保一致性。

如需绘制图标,您可以使用 Icon 可组合项,该可组合项将应用色调并提供与图标匹配的布局尺寸。

import androidx.compose.material.Icon

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

一些最常用的图标可用作 androidx.compose.material 依赖项的一部分。如需使用其他任何 Material 图标,请将 material-icons-extended 依赖项添加到 build.gradle 文件。

dependencies {
  ...
  implementation "androidx.compose.material:material-icons-extended:$compose_version"
}

字体

如需在 Compose 中使用字体,请下载字体文件,并将其放在 res/font 文件夹中以直接捆绑到 APK 中。

使用 Font API 加载每种字体,并使用这些字体创建一个 FontFamily,您可以在 TextStyle 实例中使用该 FontFamily 来创建您自己的 Typography。以下代码摘自 Crane Compose 示例及其 Typography.kt 文件。

// 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()
    }
}

如需详细了解排版,请参阅 Compose 中的主题文档。