前言
Android 8.0 發(fā)布已經(jīng)有一段時間了笤喳,本文不講新功能,講講資源國際化方面 Android 8.0 的踩坑及填坑經(jīng)歷碌宴。
項目中要求應(yīng)用內(nèi)切換語言杀狡,并且不同語言也對應(yīng)不同的語言字體(參考了這兩個庫 perfectLanguageUpdateNoNeedRestart、FontometricsLibrary )贰镣,不同語言對應(yīng)不同的布局文件呜象。
三個部分
- 切換語言
- 切換 layout 文件
- 切換 raw 文件
切換語言
Android 8.0 之前切換語言只需要以下代碼
Resources resources = getContext().getResources();
DisplayMetrics dm = resources.getDisplayMetrics();
Configuration config = resources.getConfiguration();
config.locale = Locale.ENGLISH; // 應(yīng)用用戶選擇語言
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 文件
項目需求比較復(fù)雜,我的 layout 文件目錄是這樣的:
Android 8.0 之前上煤,執(zhí)行了上面代碼休玩,當你切換界面的時候,應(yīng)該能顯示對應(yīng)語言下的
layout
文件劫狠。比如把 Locale
設(shè)置成中文簡體拴疤,R.layout
文件將調(diào)用 layout-zh-rCN
目錄下的界面,但是 Android 8.0 仍然執(zhí)行了默認 layout 目錄下面的界面嘉熊。解決思路仍然是用 applicationContext
替代 context
遥赚。項目里對 layout 文件的使用有兩處:
- Activity 的
setContentView(R.layout.…)
- Fragment 的
inflater.inflate(R.layout.…, container, false)
針對 Fragment 容易解決,我發(fā)現(xiàn) inflate 有兩個重載方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {……}
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {……}
其中第二個方法的第一個參數(shù) parser
, 可以這樣獲得:getContext().getApplicationContext().getResources().getLayout(R.layout.…)
, 于是在 fragment
中獲得布局文件就可以這樣寫 inflater.inflate(getContext().getApplicationContext().getResources().getLayout(R.layout.……), container, false);
fragment
的問題解決了阐肤,activity
的 setContentView
確沒有相應(yīng)的方法凫佛。解決方案也很粗暴,就是在 activity
中添加一個充滿全局 fragment
孕惜,然后將原 activity
的代碼交由 fragment
管理愧薛,在 fragment
中獲取多資源布局。
切換 raw 文件
為了給不同語言設(shè)置不同字體文件衫画,參考并且修改了 FontometricsLibrary 的代碼毫炉,現(xiàn)在我的 raw
目錄是這樣的:
raw
轉(zhuǎn)換成 InputStream
代碼如下:
InputStream mInputStream = context.getApplicationContext().getResources().openRawResource(R.raw.…);
重點還是獲得 applicationContext
總結(jié)
在 Android 8.0 國際化的時候,所有需要 context
的地方必須用 applicationContext
削罩。