【问题标题】:Android Jetpack Compose Localisation issueAndroid Jetpack Compose 本地化问题
【发布时间】:2021-12-18 00:11:40
【问题描述】:

尝试将 Compose 慢慢集成到我们的应用中。 该应用在几个国家/地区发布,因此我们支持英语以外的其他语言。

在使用 Compose 的第一步中,我们正在尝试迁移“更改密码”屏幕。 这是一个小代码sn-p:

@Composable
fun ChangePasswordScreen() {
    Scaffold(
        topBar = {
            CustomTopBarWithBackArrow(title = stringResource(id = R.string.a_change_password))
        },
        modifier = Modifier
            .background(Color.White)
            .fillMaxSize(),
        content = {
            ChangePasswordScreenContent()
        }
    )
}

@Composable
fun ChangePasswordScreenContent() {
    Column(
        modifier = Modifier
            .padding(16.dp)
            .background(colorResource(id = R.color.white))
            .fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        PasswordInput(
            title = stringResource(id = R.string.d_current_password),
            placeholder = stringResource(id = R.string.e_password_length)
        )
    }
}

@Composable
fun PasswordInput(title: String, placeholder: String) {
    TextFieldTitle(title = title)
    PasswordTextField(placeholder = placeholder)
}

我正在使用 stringResource 方法。 用户可以更改所选国家,并根据该国家更新区域设置。 由于某种原因,stringResource 方法不会更新为最新的 Locale,除非我们重新启动应用程序。

LocalConfiguration.current.locales[0].country 总是返回正确的国家代码。但是资源没有更新。

有没有人找到可能的解决方案? 或者,我是否遗漏了什么?

【问题讨论】:

  • 如何更改国家/地区?组合物是否会随着国家/地区的变化而重新组合?
  • 我实际上有另一个屏幕供用户选择一个国家。并根据该选择更新语言环境。我执行“Locale.setDefault(newLocale)”,然后执行“context.resources.configuration.setLocale(newLocale)”

标签: android kotlin localization android-jetpack-compose androidx


【解决方案1】:

以编程方式更改语言/区域不会重构您的 UI。您要么必须更新各种屏幕/可组合的状态,要么重新启动您的应用程序。更新您的屏幕/组合可能会很痛苦。你最好重新开始活动:

startActivity(Intent.makeRestartActivityTask(this.intent?.component))

更好的解决方案是使用 Jetmagic。它是一个旨在处理设备配置更改而无需重新启动应用程序的框架。一个演示应用程序显示了区域设置是如何更新的:

https://github.com/JohannBlake/Jetmagic

【讨论】:

  • 说实话,我想避免重新启动活动。我正在尝试遵循单一活动的做法,如果我重新开始活动,可能会导致连锁反应!
  • @georgeKele 然后你将不得不触发你的根可组合的重组。
【解决方案2】:

根据 Johann 的回答,您可以尝试手动触发重组。

试试这个,

setContent{
var trigger by mutableStateOf(false)
}

然后,在您更改Locale 的地方,只需trigger = !trigger。现在,由于setContent 方法正在读取它,整个屏幕将重新组合。

无论如何,如果您的 Locale Changer 位于非 Compose 范围内的 setContent 之外的某个位置,您可以在活动顶部声明此变量,然后像在 setContent 中那样键入它

setContent{
 trigger
 ...
}

这只是为了给 Compose 一个消息,表明此触发器正在被 setContent 读取,并且它应该在其值更改时重新组合。由于我们并不真正关心trigger 的值是什么,因此您完全可以不用remember 来编写它。

我觉得很干净,

【讨论】:

    猜你喜欢
    • 2021-09-20
    • 2023-03-03
    • 1970-01-01
    • 2022-11-12
    • 2021-10-13
    • 2021-06-29
    • 2022-10-23
    • 2021-10-28
    • 1970-01-01
    相关资源
    最近更新 更多