Android开发Android开发经验谈Android 开发相关文章收集

Android 8.0 资源国际化适配

2017-12-11  本文已影响1845人  Crazy_MT

前言

Android 8.0 发布已经有一段时间了,本文不讲新功能,讲讲资源国际化方面 Android 8.0 的踩坑及填坑经历。
项目中要求应用内切换语言,并且不同语言也对应不同的语言字体(参考了这两个库 perfectLanguageUpdateNoNeedRestartFontometricsLibrary ),不同语言对应不同的布局文件。


三个部分


切换语言

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 文件的使用有两处:
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 的问题解决了,activitysetContentView确没有相应的方法。解决方案也很粗暴,就是在 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

Demo在此

上一篇 下一篇

猜你喜欢

热点阅读