Android 實現APP可切換多語言

原文: Android 實現APP可切換多語言 - Stars-One的雜貨小窩

如果是單獨給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)獲取了

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章