You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中实现应用语言区域(Locale)的动态切换?

需要调整的代码分为三部分,具体修改如下:


1. 优化语言切换工具函数

你原有setLocaleLang不支持带地区的语言编码(比如zh-rTW、zh-rCN),且高版本Android适配不全,替换为以下代码:

fun setLocaleLang(lang: String, context: Context) {
    val locale = when {
        lang.contains("-r") -> {
            val (langCode, regionCode) = lang.split("-r")
            Locale(langCode, regionCode)
        }
        lang.isNotEmpty() -> Locale(lang)
        else -> Resources.getSystem().configuration.locales[0]
    }
    Locale.setDefault(locale)
    val resources = context.resources
    val configuration = resources.configuration.apply {
        setLocale(locale)
        // 适配Android 7.0+的多语言列表规则
        setLocales(LocaleList(locale))
    }
    resources.updateConfiguration(configuration, resources.displayMetrics)
    // 持久化存储选择的语言
    context.getSharedPreferences("Settings", Context.MODE_PRIVATE)
        .edit()
        .putString("My_Lang", lang)
        .apply()
}

// 修复原有loadLocale的空指针风险
fun loadLocale(context: Context) {
    val sharedPref = context.getSharedPreferences("Settings", Activity.MODE_PRIVATE)
    val language = sharedPref.getString("My_Lang", "") ?: ""
    setLocaleLang(language, context)
}

2. 修改LanguageScreen的点击逻辑

语言配置更新后需要触发Activity重建才能让Compose全局刷新资源,在clickable代码块的最后添加重建逻辑:

.clickable {
    // 你原有选中状态更新逻辑保持不变
    items = items.mapIndexed { j, item ->
        if (i == j) item.copy(isSelected = true) else item.copy(isSelected = false)
    }
    // 你原有调用setLocaleLang的逻辑保持不变
    if (i == 0) {
        setLocaleLang("", context)
    } else if (i == 1) {
        setLocaleLang("zh-rTW", context)
    } else if (i == 2) {
        setLocaleLang("zh-rCN", context)
    } else {
        setLocaleLang("ja", context)
    }
    // 新增:触发Activity重建,刷新所有Compose界面的语言
    val activity = context as ComponentActivity
    activity.recreate()
}

3. 修改MainActivity.kt

重写attachBaseContext方法,保证Activity启动时优先加载你存储的语言配置,修改后完整代码如下:

class MainActivity : ComponentActivity() {
    // 新增重写方法
    override fun attachBaseContext(newBase: Context?) {
        newBase?.let { loadLocale(it) }
        super.attachBaseContext(newBase)
    }

    @ExperimentalFoundationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        // 这行可以保留,不会冲突
        loadLocale(this)
        super.onCreate(savedInstanceState)
        setContent {
            SpanishTravelTheme {
                // 你原有界面逻辑保持不变
            }
        }
    }
}

完成以上修改后,点击语言选项即可触发全局语言切换,所有使用stringResource加载的字符串资源会自动匹配当前选中的语言。

内容的提问来源于stack exchange,提问作者Justin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 07:45:03