如何在 Android Jetpack Compose 中使用字符串资源?

Posted

技术标签:

【中文标题】如何在 Android Jetpack Compose 中使用字符串资源?【英文标题】:How to use string resources in Android Jetpack Compose? 【发布时间】:2021-04-29 12:14:46 【问题描述】:

让我有以下strings.xml 资源文件:

<resources>
    <!-- basic string -->
    <string name="app_name">My Playground</string>

    <!-- basic string with an argument -->
    <string name="greeting">Hello %!</string>

    <!-- plural string -->
    <plurals name="likes">
        <item quantity="one">%1d like</item>
        <item quantity="other">%1d likes</item>
    </plurals>

    <!-- string array -->
    <string-array name="planets">
        <item>Earth</item>
        <item>Mars</item>
    </string-array>
</resources>

如何在 Jetpack Compose 中使用这些资源?

【问题讨论】:

【参考方案1】:

androidx.compose.ui.res 包包含用于加载字符串资源以及其他资源类型的函数。

字符串

可以使用stringResource()函数获取字符串,例如:

...
import androidx.compose.ui.res.stringResource

@Composable
fun StringResourceExample() 
  Text(
    // a string without arguments
    text = stringResource(R.string.app_name)
  )

  Text(
    // a string with arguments
    text = stringResource(R.string.greeting, "World")
  )

字符串数组

可以使用stringArrayResource()函数获取:

val planets = stringArrayResource(R.array.planets_array)

复数(数量字符串)

从 compose 1.0.0-alpha10 开始,没有用于获取复数资源的内置函数,但您可以通过 LocalContext 获取 android 上下文,并以与在基于视图的应用程序中相同的方式使用它。如果您创建自己的类似于其他资源函数的函数会更好(例如Jetcaster compose sample):

// PluralResources.kt

package com.myapp.util

import androidx.annotation.PluralsRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext

@Composable
fun quantityStringResource(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): String 
    return LocalContext.current.resources.getQuantityString(id, quantity, *formatArgs)

所以你可以以同样的方式使用它:

val likes = quantityStringResource(R.plurals.likes, 10, 10)

关于重组的说明

如您所知,在 compose 中,可组合函数在 recomposition 期间每秒可能重新执行数百次。如果你构建的字符串不是微不足道的,需要进行一些计算,最好将计算结果remember,这样就不会在每次重组时重新执行。例如:

...

import androidx.compose.runtime.remember

@Composable
fun BirthdayDateComposable(username: String, dateMillis: Long) 
  // formatDate() function will be executed only if dateMillis value 
  // is changed, otherwise the remembered value will be used
  val dateStr = remember(dateMillis) 
    formatDate(dateMillis)
  

  Text(
    text = stringResource(R.string.birthday_date, dateStr)
  )

【讨论】:

关于重组,你确定在这个例子中需要remember吗? official documentation 建议如果可组合函数的参数保持不变,则不会重组:“通过跳过所有未更改参数的函数或 lambda,Compose 可以有效地重组。”

以上是关于如何在 Android Jetpack Compose 中使用字符串资源?的主要内容,如果未能解决你的问题,请参考以下文章

Jetpack Compose - Slider

Android Jetpack Navigation:如何在 OnNavigatedListener 中获取目的地的片段实例?

使用Android Jetpack导航时如何防止导航

如何在使用Android Jetpack导航时禁用导航图标

如何在 Android Jetpack Compose 中将 Dp 转换为像素?

如何在 Android Jetpack Compose 中使用字符串资源?