如何使用Jetpack Compose实现应用程序内本地化?我的意思是,我不希望用户更改他们的设备语言,相反,让他们只更改应用程序语言.如何做到这一点?我找到的所有资源都在谈论改变设备语言.

推荐答案

这是我根据这个答案here做的.

在应用程序类中,执行以下操作:

class MyApp : Application() {
    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(LocaleHelper.setLocale(base, myLang))
    }

    companion object {
        var myLang = "en"
    }
}

我将语言保存在myLang变量中,但实际上您将保存在Shared Preferences中.

onAttachBaseContext中,setLocale被称为(它在下面声明).

然后,在你的活动中,你也会这样做:

class MainActivity : AppCompatActivity() {
    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(
            LocaleHelper.setLocale(newBase, MyApp.myLang)
        )
    }
}

下面的对象将在MyApp.myLang中设置语言并更新Context对象.

object LocaleHelper {
    fun setLocale(context: Context, language: String): Context? {
        MyApp.myLang = language
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, language);
        }
        return updateResourcesLegacy(context, language);
    }

    @TargetApi(Build.VERSION_CODES.N)
    private fun updateResources(context: Context, language: String): Context? {
        val locale = Locale(language)
        Locale.setDefault(locale)
        val configuration = context.resources.configuration
        configuration.setLocale(locale)
        configuration.setLayoutDirection(locale)
        return context.createConfigurationContext(configuration)
    }

    private fun updateResourcesLegacy(context: Context, language: String): Context {
        val locale = Locale(language)
        Locale.setDefault(locale)
        val resources = context.resources
        val configuration = resources.configuration
        configuration.locale = locale
        resources.updateConfiguration(configuration, resources.displayMetrics)
        return context
    }
}

最后,在composable中,您可以执行以下操作:

@Composable
fun TestLanguage() {
    val context = LocalContext.current
    Text(text = stringResource(id = R.string.activity_java_text))
    Button(onClick = {
        LocaleHelper.setLocale(context, "pt")
        (context as? Activity)?.recreate()
    }) {
        Text(text = stringResource(id = R.string.btn_ok))
    }
}

注意,调用recreate方法来重新创建当前活动并应用语言更改.

Android相关问答推荐

如何将文本相对于喷气背包中的图标垂直居中?

Jetpack Compose make父级图像填充高度

道查询注释部分房间表名称

无法安装后重新编译android代码'

如何将子零部件的大小调整为可以调整大小的父组件大小?

使用Retrofit2的API调用:我如何能够一直进行API调用,以更新数据而无需重新打开应用程序

如何在Jetpack Compose中更新异步回调的用户界面

在androidStudio中,如何使用带有ResolutionStrategy的ResolutionSelector而不是setTargetResolve()?

我无法连接到信号机

如何在Jetpack Compose中创建这个圆形?

Jetpack Compose - 在屏幕外偏移绘制形状并使用非常大的尺寸

了解 Compose 声明性逻辑

在 Jetpack Compose 中使用 .observeAsState() 时,如何在更改 MutableLiveData 的值后开始执行一段代码?

LazyColumn 项目,隐式接收器无法在此上下文中调用单元

如何在 Android 应用程序未激活/未聚焦时显示视图?

Android:appcompat 和 material 如何从默认创建 appcompat 和 material 视图?

是什么让 Android Studio 中的按钮变成紫色?加上新手的其他奇怪行为

如何使在库范围之外无法访问的接口的具体实现.?

compose :为什么以记住启动的列表触发方式与快照不同

在 Android 10 (API 29) 中隐藏状态栏并在应用程序中使用其空间