android资源国际化,Android 8.0 资源国际化适配
前言Android 8.0 发布已经有一段时间了,本文不讲新功能,讲讲资源国际化方面 Android 8.0 的踩坑及填坑经历。项目中要求应用内切换语言,并且不同语言也对应不同的语言字体(参考了这两个库 perfectLanguageUpdateNoNeedRestart、FontometricsLibrary ),不同语言对应不同的布局文件。三个部分切换语言切换 layout 文件切换 raw
前言
Android 8.0 发布已经有一段时间了,本文不讲新功能,讲讲资源国际化方面 Android 8.0 的踩坑及填坑经历。
项目中要求应用内切换语言,并且不同语言也对应不同的语言字体(参考了这两个库 perfectLanguageUpdateNoNeedRestart、FontometricsLibrary ),不同语言对应不同的布局文件。
三个部分
切换语言
切换 layout 文件
切换 raw 文件
切换语言
Android 8.0 之前切换语言只需要以下代码
Resources resources = getContext().getResources();
DisplayMetrics dm = resources.getDisplayMetrics();
Configuration config = resources.getConfiguration();
config.locale = Locale.ENGLISH; // 应用用户选择语言
resources.updateConfiguration(config, dm);
Android 8.0 切换语言需要以下代码
Resources resources = getApplicationContext().getResources();
DisplayMetrics dm = resources.getDisplayMetrics();
Configuration config = resources.getConfiguration();
config.setLocale(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleList localeList = new LocaleList(locale);
LocaleList.setDefault(localeList);
config.setLocales(localeList);
getApplicationContext().createConfigurationContext(config);
}
Locale.setDefault(locale);
resources.updateConfiguration(config, dm);
重点: 确保 applicationContext 代替所有其它类型的 context。(至于针对 Android N 的那几行代码,实测好像没什么影响。)
切换 layout 文件
项目需求比较复杂,我的 layout 文件目录是这样的:
image.png
Android 8.0 之前,执行了上面代码,当你切换界面的时候,应该能显示对应语言下的 layout 文件。比如把 Locale 设置成中文简体,R.layout 文件将调用 layout-zh-rCN 目录下的界面,但是 Android 8.0 仍然执行了默认 layout 目录下面的界面。解决思路仍然是用 applicationContext 替代 context。
项目里对 layout 文件的使用有两处:
Activity 的 setContentView(R.layout.…)
Fragment 的 inflater.inflate(R.layout.…, container, false)
针对 Fragment 容易解决,我发现 inflate 有两个重载方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {……}
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {……}
其中第二个方法的第一个参数 parser , 可以这样获得:getContext().getApplicationContext().getResources().getLayout(R.layout.…), 于是在 fragment 中获得布局文件就可以这样写 inflater.inflate(getContext().getApplicationContext().getResources().getLayout(R.layout.……), container, false);
fragment 的问题解决了,activity 的 setContentView确没有相应的方法。解决方案也很粗暴,就是在 activity 中添加一个充满全局 fragment,然后将原 activity 的代码交由 fragment 管理,在 fragment 中获取多资源布局。
切换 raw 文件
为了给不同语言设置不同字体文件,参考并且修改了 FontometricsLibrary 的代码,现在我的 raw 目录是这样的:
image.png 将 raw 转换成 InputStream 代码如下:
InputStream mInputStream = context.getApplicationContext().getResources().openRawResource(R.raw.…);
重点还是获得 applicationContext
总结
在 Android 8.0 国际化的时候,所有需要 context 的地方必须用 applicationContext。
更多推荐
所有评论(0)