如果是單獨給app加上國際化,其實很容易,建立對應的國家資原始檔夾即可,如values-en
,values-pt
,app會根據當前系統語言去使用對應語言資原始檔,如果找不到,則使用values資料夾裡的資源
但本文講得是另外一種情況,就是app內建一個切換多語言的頁面,可以給使用者切換
步驟
1.新增服務宣告
此步驟主要是讓我們的app可記錄當前應用語言,使用的Service是android系統給我們提供的
<!-- 國際化多語言 -->
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
2.在xml資料夾增加檔案locale_config.xml
宣告支援的幾個語言
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en" />
<locale android:name="pt" />
<locale android:name="es" />
<locale android:name="de" />
<locale android:name="fr" />
</locale-config>
3.呼叫方法切換多語言
// 切換語言
val langua="en"
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(langua))
補充下其他方法:
//獲取當前應用使用語言
val locale = AppCompatDelegate.getApplicationLocales()[0]
//語言短標轉為locale物件
val langua="en"
val locale = Locale.forLanguageTag(langua)
一些坑點
1.上架谷歌市場無法切換語言
上架到谷歌市場,使用者下載只會下載其系統語言包,會導致app內建的語言切換功能無效
原因是打包為aab的時候,gradle的配置,預設是開啟了語言分包設定,我們取消這個設定就可以解決此問題
gradle配置如下
buildTypes {
release {
bundle{
//設定多語言不分包處理
language {
// Specifies that the app bundle should not support
// configuration APKs for language resources. These
// resources are instead packaged with each base and
// feature APK.
enableSplit = false
}
density {
// This property is set to true by default.
enableSplit = true
}
abi {
// This property is set to true by default.
enableSplit = true
}
}
}
}
2.使用StringUtil導致語言切換功能失效
我使用到了Blankj/AndroidUtilCode裡面的StringUtil獲取資料,到時切換多語言後會存在問題
原因是裡面StringUtil裡面使用的是application而不是Activity
最終還是更換為使用Activity物件來獲取string文字(activity.getString(R.string.hello)
)
也看到了issue有人說到這個問題,說要是更新application的資原始檔,但我測試的時候發現更新application的語言資源後,會觸發應用閃屏的效果,然後就沒有使用此方法
由於專案進度趕,就沒去細究了
3.使用靜態資料導致後續沒有文字沒有更新
因為頁面有幾個使用相同佈局的樣式,比如說常見的選單項,我是這樣的做法:
抽取出來的一個靜態類來儲存對應資料(圖示,文字之類),之後寫一個xml檔案,頁面則是使用include來引用多份相同樣式的item,最終在Activity裡給這些item賦值
由於item比較少,又不想用recyclerview,就是採用了上面的這個方法
但是如果涉及到多語言切換的話,就會導致沒有資料及時更新
原因是更換語言後,是Activity進行的重新建立,但我們儲存資料的類還是存在的,裡面文字資料並沒有更新,所以就是導致了這個問題
解決方法簡單粗暴,就每次Activity的onCreate方法裡建立對應的資料物件即可,這樣,Activity重建之後我們的文字資料就會重新呼叫activity.getString(R.string.hello)
獲取了