android - Android:如何以编程方式更改应用程序语言?
问题描述
我想以编程方式更改我的应用程序语言。我有一些适用于旧手机(Android 6)的代码,但它不适用于 Android 8 和 Android 9。任何适用于应用语言更改的解决方案?调用 setLocal 后,我在 Activity 中调用 recreate()。字符串仍然没有变化。
在我MainActivity
的扩展BaseActivity
中,onCreate()
如果我调用Locale.getDefault().language
它,它会返回正确的语言代码,但字符串仍然是英语,这是默认的string.xml
。
fun setLocale(context: Context, language: String?): Context {
app.setLanguage(language)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResources(context, language)
} else updateResourcesLegacy(
context,
language
)
}
@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String?): Context {
val locale =
if (language == null){
Locale(Locale.getDefault().language)
} else {
Locale(language)
}
Locale.setDefault(locale)
val configuration = context.resources.configuration
configuration.setLocale(locale)
return context.createConfigurationContext(configuration)
}
@Suppress("DEPRECATION")
private fun updateResourcesLegacy(context: Context, language: String?): Context {
val locale =
if (language == null){
Locale(Locale.getDefault().language)
} else {
Locale(language)
}
Locale.setDefault(locale)
val resources = context.resources
val configuration = resources.configuration
configuration.locale = locale
resources.updateConfiguration(configuration, resources.displayMetrics)
return context
}
更新:我使用了以下两种解决方案的组合,但仍然没有成功。我BaseActivity
上课的时间因我的所有活动而延伸。在那里我调用changeLocale
了类似于 LocaleHelper 的函数。app.getSavedLanguage()
在我的sharedPrefs
. 此代码会根据用户在应用程序中选择的语言被覆盖。App 是使用共享首选项的应用程序类。
override fun onCreate(si: Bundle?) {
super.onCreate(si)
app = application as App
changeLocale(this, app.getSavedLanguage())
}
open fun changeLocale(context: Context, lang: String) {
val newLocale = Locale(lang)
Locale.setDefault(newLocale)
val res: Resources = context.resources
val conf: Configuration = res.configuration
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
conf.apply {
setLocale(newLocale)
setLayoutDirection(newLocale)
}
context.createConfigurationContext(conf)
} else {
conf.apply {
locale = newLocale
setLayoutDirection(newLocale)
}
res.updateConfiguration(conf, res.displayMetrics)
}
}
解决方案
onCreate()
之前可以在 MainActivity 中使用这个配置setContentView()
@Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
String appLang = sharedPreferences.getString("appLanguage", Locale.getDefault().getLanguage());
Locale myLocale = new Locale(appLang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
Locale.setDefault(myLocale);
conf.setLayoutDirection(myLocale);
res.updateConfiguration(conf, dm);
setContentView(R.layout.activity_main);
}
推荐阅读
- arrays - 使用带有附加参数的自定义规则验证 Laravel 中的数组
- tsql - 从单个数据表中写入每个帐户的所有天数
- java - Java 开端
- mysql - 由来自不同表的聚合数据组成的简单 MySQL 视图
- python-3.x - Tkinter 标签文本未出现
- javascript - 如何将 dropzone.js 选择的预览图像重定向到新页面?
- pandas - 如何解释熊猫数据框布尔索引的结果
- reactjs - 在 React 中实现 github.io/project 上的相对路径
- c - 除了与函数指针一起使用之外,是否有在 C 中对函数进行类型定义的目的?
- leaflet - 将图像添加到地图并确保纵横比正确