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

如何在Kotlin Compose中手动切换语言?解决updateConfiguration过时问题

替换过时的updateConfiguration()实现Compose手动语言切换

原代码中updateConfiguration()已被标记为过时,以下是使用createConfigurationContext()和CompositionLocalProvider的替代实现方案:

1. 自定义Application类管理全局Locale

class MyApp : Application() {
    private var currentLocale: Locale = Locale.getDefault()

    // 更新全局Locale
    fun updateLocale(newLocale: Locale) {
        currentLocale = newLocale
        Locale.setDefault(currentLocale)
    }

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(updateContextLocale(base))
    }

    // 创建包含指定Locale的Context
    private fun updateContextLocale(context: Context): Context {
        val configuration = Configuration(context.resources.configuration)
        configuration.setLocale(currentLocale)
        return context.createConfigurationContext(configuration)
    }
}

2. 修改MainActivity实现语言初始化与Compose上下文传递

@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
class MainActivity : ComponentActivity() {
    private lateinit var viewModel: LanguageViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel = ViewModelProvider(this)[LanguageViewModel::class.java]

        // 从SharedPreferences读取保存的语言设置
        val sharedPrefs = getSharedPreferences("Preferences", MODE_PRIVATE)
        val savedLanguage = sharedPrefs.getString("language", getString(R.string.english))
        val targetLocale = when(savedLanguage ?: getString(R.string.english)) {
            getString(R.string.hungarian) -> Locale("hu")
            else -> Locale("en")
        }
        // 更新Application的全局Locale
        (application as MyApp).updateLocale(targetLocale)

        setContent {
            // 创建本地化的Context并通过CompositionLocal传递给Compose树
            val localizedContext = LocalContext.current.createConfigurationContext(
                Configuration().apply { setLocale(targetLocale) }
            )
            CompositionLocalProvider(LocalContext provides localizedContext) {
                val windowSize = calculateWindowSizeClass(this@MainActivity).heightSizeClass
                App(isExpanded = windowSize != WindowHeightSizeClass.Compact, viewModel = viewModel)
            }
        }
    }

    override fun onPause() {
        super.onPause()
        // 保存当前选中的语言到SharedPreferences
        val sharedPrefs = getSharedPreferences("Preferences", MODE_PRIVATE)
        sharedPrefs.edit()
            .putString("language", viewModel.uiState.value.actualLanguage)
            .apply()
    }
}

3. 调整ViewModel的语言切换逻辑

class LanguageViewModel : ViewModel() {
    private val _uiState = MutableStateFlow(LanguageUiState())
    val uiState = _uiState.asStateFlow()

    // 更新选中的语言选项
    fun updateSelectedLanguage(lang: String) {
        _uiState.update { it.copy(selectedLanguage = lang) }
    }

    // 应用语言切换
    fun onSettingsApplyClicked(context: Context) {
        val currentLang = uiState.value.actualLanguage
        val selectedLang = uiState.value.selectedLanguage
        if (currentLang != selectedLang) {
            _uiState.update { it.copy(actualLanguage = selectedLang) }
            // 重启Activity以加载新的语言配置
            val intent = Intent(context, MainActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            }
            context.startActivity(intent)
        }
    }

    // 语言状态数据类
    data class LanguageUiState(
        val actualLanguage: String = "English",
        val selectedLanguage: String = "English"
    )
}

关键说明

  • 使用createConfigurationContext()创建包含目标Locale的新Context,完全替代过时的updateConfiguration()
  • 通过CompositionLocalProvider将本地化Context注入Compose树,确保所有Compose组件使用正确的语言资源
  • 在Application层处理Locale初始化,保证App启动时的语言配置正确
  • 语言切换后通过重启Activity让新的Locale配置全局生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:10:41