为满足Android App更广泛的使用度,通常会包含多语言版本,根据用户的选择,自动加载相应的语言包,并更新界面显示。该过程主要可划分为两步:
1)加入不同语言对应的资源包;
2)根据选择切换界面语言的显示。
语言资源包
任何保存在工程res下的资源文件都可以根据语言保存在不同的资源包中,这里仅以res下的strings.xml为例。
默认的Android工程在res/values下会包含strings.xml,该文件没有语言的适配功能,在没有指定显示语言环境时默认使用,当然也可使用于任何语言环境下;如果设定了语言环境,当某string在对应的语言包下没有相应的注释,则也会在默认的string.xml中查找对应注释。
在values下选择新建资源文件Valus Resource files 微信图片_20181014165842.png如何新建简体中文和英文的语言包?
file name中输入strings.xml,在下方的available qualifiers中选择Locale,其作用是为当前的xml文件加入属性。区域属性包含语言代码和区域代码,可选范围分别列举在Language和Specific Region Only两列表下,选择后即为该语言包设置标签,在语言环境匹配时加载对应的语言包。
如何获取当前的语言环境?
Android中通过configuration获取当前语言设置,根据版本不同有如下两种方式:
1)API >= 17时已废弃
Locale locale = context.getResources().getConfiguration().locale;
2)在 API >= 17 的版本上可以使用
LocaleList localeList = context.getResources().getConfiguration().getLocales();
Locale locale = localeList.get(0);
之后可通过
String language = locale.getLanguage();
String country = locale.getCountry();
分别获得当前的语言设置和区域设置。
如何设置语言包?
根据上面获取当前语言设置的过程可以看出,设置语言的过程是作用于context的。
更新configuration的过程如下:
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Resources resources = context.getResources();
Locale locale = AppLanguageUtils.getLocaleByLanguage(language);
Configuration configuration = resources.getConfiguration();
configuration.setLocale(locale);
configuration.setLocales(new LocaleList(locale));
return context.createConfigurationContext(configuration);
}
如何改变语言环境?
更新语言包,更改configuration的设置后,需要重新启动activity才能正确加载。
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
//TargetActiviy的launchMode为singleInstance时,CurrentActivity和TargetActvity不在一个Task栈
//需要完全终止当前应用后再重启,才能正确加载新的设置
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
如果希望重新加载当前activity,使用recreate()方法即可。
语言设置的过程需要作用于每一个activity。创建activity的基类BaseActivity,并在其中重写如下方法可以免去在每个activity中都重复相同的方法描述。
@Override
protected void attachBaseContext(Context newBase)
{
super.attachBaseContext(updateResources(context, language));
}
activity启动前会先进这里加载对应的语言包,之后执行onCreate。
网友评论