Android 實現APP可切換多語言

one發表於2023-11-29

原文: 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)獲取了

參考

相關文章