如何在Kotlin中实现Android应用运行时换语言并消除黑屏
Android运行时切换语言消除黑屏方案
问题分析
你当前的代码通过recreate()重建Activity实现语言切换,但该操作会触发Activity销毁重建流程,进而引发黑屏。要解决这个问题,核心是避免Activity重建,改为全局统一维护语言配置并手动刷新UI。
解决方案步骤
1. 全局维护语言配置(Application类)
在Application中统一处理Locale设置,确保所有组件共享同一语言环境,同时持久化用户的语言选择:
class MyApp : Application() { override fun onCreate() { super.onCreate() // 初始化时加载已保存的语言设置 updateAppLocale(getSavedLanguage()) } // 更新应用全局Locale fun updateAppLocale(languageCode: String) { val locale = Locale(languageCode) Locale.setDefault(locale) val config = resources.configuration.apply { setLocale(locale) setLayoutDirection(locale) } resources.updateConfiguration(config, resources.displayMetrics) } // 读取本地保存的语言设置 private fun getSavedLanguage(): String { return getSharedPreferences("app_prefs", MODE_PRIVATE) .getString("selected_language", "en") ?: "en" } // 保存用户选择的语言 fun saveLanguage(languageCode: String) { getSharedPreferences("app_prefs", MODE_PRIVATE) .edit() .putString("selected_language", languageCode) .apply() } }
记得在AndroidManifest.xml中注册这个Application:
<application android:name=".MyApp" ...> ... </application>
2. 修改Fragment中的切换逻辑(移除recreate())
去掉recreate()调用,改为更新全局Locale后手动刷新当前Fragment的UI:
fun setLocale(languageCode: String) { Log.d("important", "Accessed with: $languageCode") // 保存语言设置并更新全局Locale val app = requireContext().applicationContext as MyApp app.saveLanguage(languageCode) app.updateAppLocale(languageCode) // 手动刷新当前Fragment的所有文本控件 refreshFragmentUI() } private fun refreshFragmentUI() { // 示例:重新设置所有显示字符串的View tv_title.text = getString(R.string.title) btn_submit.text = getString(R.string.submit) // 若有RecyclerView,需调用adapter.notifyDataSetChanged()刷新列表项文本 }
3. 处理配置变化(BaseActivity)
创建BaseActivity,让所有业务Activity继承它,确保页面创建时自动应用保存的语言设置,避免系统配置变化覆盖自定义语言:
open class BaseActivity : AppCompatActivity() { override fun attachBaseContext(newBase: Context) { // 读取保存的语言设置 val languageCode = newBase.getSharedPreferences("app_prefs", MODE_PRIVATE) .getString("selected_language", "en") ?: "en" val locale = Locale(languageCode) val config = newBase.resources.configuration.apply { setLocale(locale) setLayoutDirection(locale) } val context = newBase.createConfigurationContext(config) super.attachBaseContext(context) } }
关键说明
- 手动刷新UI代替Activity重建,彻底消除黑屏问题。
- 全局统一维护Locale,确保整个应用语言环境一致。
- 持久化语言设置,应用重启后保持用户的语言选择。
- 若有复杂布局或列表控件,需针对性刷新对应组件的文本内容。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

