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

字符串复数(实验性)

使用 pluralStringResource API 加载具有特定数量的复数。

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

使用 pluralStringResource 方法时,如果您的字符串包含带数字的字符串格式化,则需要传递两次计数。例如,对于字符串 %1$d minutes,第一个计数参数选择合适的复数字符串,第二个计数参数插入到 %1$d 占位符中。如果您的复数字符串不包含字符串格式化,则无需将第三个参数传递给 pluralStringResource

有关复数的更多信息,请查看数量字符串文档

尺寸

类似地,使用 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="purple_200">#FFBB86FC</color>

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

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 在主线程上解码和解析资源内容。

动画矢量可绘制对象

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

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

图标

Jetpack Compose 带有 Icons 对象,它是用于在 Compose 中使用Material Icons 的入口点。有五个不同的图标主题:填充轮廓圆角双色调锐利。每个主题包含相同的图标,但具有不同的视觉风格。您通常应选择一个主题并在整个应用程序中使用它以保持一致性。

要绘制图标,您可以使用Icon 可组合项,它应用色调并提供与图标匹配的布局大小。

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

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

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

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

字体

要在 Compose 中使用字体,请下载并将字体文件直接捆绑到 APK 中,方法是将它们放在 res/font 文件夹中。

使用Font API 加载每个字体,并使用它们创建FontFamily,您可以在TextStyle 实例中使用它来创建您自己的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(
    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()
    }
}

有关在 Compose 中使用可下载字体的更多信息,请参阅可下载字体页面。

Compose 主题文档中了解有关排版的更多信息