如何在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
相关产品推荐
相关产品推荐

