Android使用AndroidUtilCode實現(xiàn)多語言
一、項目中配置多語言
多語言的實現(xiàn)是通過AndroidUtilCode實現(xiàn)的,表示感謝!
項目里面有4種語言:中文,英文,德文,俄文。文件夾如下:

配置多語言的思路是:
1、判斷是否為國內(nèi)版本,如果為國內(nèi)版本則設(shè)置為簡體中文
2、 如果為國外版本,獲取用戶之前設(shè)置的App語言,如果用戶之前有設(shè)置App語言,則設(shè)置為之前用戶設(shè)置的語言;如果用戶之前沒有設(shè)置App語言則獲取手機系統(tǒng)的語言。
3、判斷當前手機系統(tǒng)的語言是否App有做語言適配,如果有適配則設(shè)置成跟手機系統(tǒng)一樣的語言,如果沒有適配則設(shè)置為英文。
二、具體實現(xiàn)
1、初始化PropertiesUtil和MMKV,具體代碼請參考上篇博客
2、在BaseApplication中設(shè)置語言
abstract class BaseApplication : Application() {
abstract fun init()
override fun onCreate() {
super.onCreate()
init()
PropertiesUtil.init(this)
MMKV.initialize(this)
MMKVUtil.setUserId(1000L)
//設(shè)置App語言
setAppLanguage()
}
/**
* 判斷是否為國內(nèi)版本,如果為國內(nèi)版本則設(shè)置為簡體中文
* 如果為國外版本,獲取用戶之前設(shè)置的App語言,
* 如果用戶之前有設(shè)置App語言,則設(shè)置為之前用戶設(shè)置的語言
* 如果用戶之前沒有設(shè)置App語言則獲取手機系統(tǒng)的語言
* 判斷手機系統(tǒng)的語言是否App有做語言適配,如果有適配則設(shè)置成跟手機系統(tǒng)一樣的語言
* 如果App沒有對當前系統(tǒng)語言做適配則設(shè)置為英文
*/
private fun setAppLanguage() {
if (PropertiesUtil.isCN()) { //國內(nèi)版本
LanguageUtils.applyLanguage(Locale.SIMPLIFIED_CHINESE, false)
} else {
MMKVUtil.getLanguage().also {
if (it.isNotEmpty()) {
setLanguageAndBackCountry(it)
} else {
//獲取系統(tǒng)語言
LanguageUtils.getSystemLanguage().country.also { country ->
setLanguageAndBackCountry(country).also { value ->
//保存設(shè)置的語言
MMKVUtil.setLanguage(value)
}
}
}
}
}
}
private fun setLanguageAndBackCountry(it: String): String {
return when (it) {
LanguageType.CN.name -> {
LanguageUtils.applyLanguage(Locale.SIMPLIFIED_CHINESE, false)
it
}
LanguageType.US.name -> {
LanguageUtils.applyLanguage(Locale.ENGLISH, false)
it
}
LanguageType.DE.name -> {
LanguageUtils.applyLanguage(Locale.GERMANY, false)
it
}
LanguageType.RU.name -> {
LanguageUtils.applyLanguage(Locale("ru"), false)
it
}
else -> {
LanguageUtils.applyLanguage(Locale.ENGLISH, false)
LanguageType.US.name
}
}
}
}
3、切換語言
比如設(shè)置為德文,按鈕觸發(fā):
MMKVUtil.setLanguage(LanguageType.DE.name) LanguageUtils.applyLanguage(Locale.GERMANY, false) //true:重啟App false:不重啟App
4、注意gradle配置resConfigs不要限制為只有中文,比如:resConfigs "zh-rCN", "en"
三、AndroidX和多進程存在的問題
1、多進程讀取Configuration時發(fā)現(xiàn)其他進程與主進程獲取的Configuration值不一致,導(dǎo)致主進程切換語言后其他語言并沒有切換成功。
2、AndroidX切換失敗的問題,具體可以看下這篇博客【踩坑記錄】多語言切換在Androidx失效
解決辦法:重寫Activity的attachBaseContext方法,修改Context
/**
* 多語言的切換類, 解決多進程切換語言失敗的問題以及AndroidX多語言切換失效的問題
* 解決由于 WebView 初始化會修改 Activity 語種配置,間接導(dǎo)致 Activity 語種會被還原,所以需要你手動重寫 WebView 對這個問題進行修復(fù)
*/
object MultiLanguageUtil {
fun getAttachBaseContext(context: Context): Context {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
configAppcompatLanguage(setAppLanguageApi24(context))
} else {
setAppLanguage(context)
configAppcompatLanguage(context)
}
}
/**
* 設(shè)置應(yīng)用語言
*/
@Suppress("DEPRECATION")
private fun setAppLanguage(context: Context) {
val resources = context.resources
val displayMetrics = resources.displayMetrics
val configuration = resources.configuration
// 獲取當前系統(tǒng)語言,默認設(shè)置跟隨系統(tǒng)
val locale = getLocale()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLocale(locale)
} else {
configuration.locale = locale
}
resources.updateConfiguration(configuration, displayMetrics)
}
/**
* 兼容 7.0 及以上
*/
@TargetApi(Build.VERSION_CODES.N)
fun setAppLanguageApi24(context: Context): Context {
val locale = getLocale()
val resource = context.resources
val configuration = resource.configuration
configuration.setLocale(locale)
configuration.setLocales(LocaleList(locale))
return context.createConfigurationContext(configuration)
}
private fun configAppcompatLanguage(context: Context): Context {
val configuration = context.resources.configuration
//兼容appcompat 1.2.0后切換語言失效問題
return object : ContextThemeWrapper(context, R.style.Base_Theme_AppCompat_Empty) {
override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
overrideConfiguration?.setTo(configuration)
super.applyOverrideConfiguration(overrideConfiguration)
}
}
}
private fun getLocale(): Locale {
return when (CacheUtil.getInt(GlobalConstants.LANGUAGE_KEY, true)) {
0 -> {
Locale.SIMPLIFIED_CHINESE
}
1 -> {
Locale.ENGLISH
}
2 -> {
Locale.GERMANY
}
3 -> {
Locale("ru")
}
else -> Locale.ENGLISH
}
}
/**
* 解決WebView多語言失效的問題
*/
fun updateLanguage(context: Context) {
val resources = context.resources
val config = resources.configuration
val settingLanguage = getLocale().language
val systemLanguage = config.locales[0].language
if (settingLanguage != systemLanguage) {
setLocale(config, Locale(settingLanguage))
resources.updateConfiguration(config, resources.displayMetrics)
}
}
private fun setLocale(config: Configuration, locale: Locale?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val localeList = LocaleList(locale)
config.setLocales(localeList)
} else {
config.setLocale(locale)
}
} else {
config.locale = locale
}
}
}
獲取appContext
lateinit var appContext: Application
//BaseApplication中調(diào)用方法獲取Application的上下文
fun BaseApplication.getContext(application: BaseApplication) {
appContext = application
}
四、WebView導(dǎo)致的語言重置的問題
由于 WebView 初始化會修改 Activity 語種配置,間接導(dǎo)致 Activity 語種會被還原,所以需要你手動重寫 WebView 對這個問題進行修復(fù),如下:
/**
* 由于 WebView 初始化會修改 Activity 語種配置,間接導(dǎo)致 Activity 語種會被還原回去,所以需要你手動重寫 WebView 對這個問題進行修復(fù)
*/
class LanguagesWebView(
context: Context,
@Nullable attrs: AttributeSet?,
defStyleAttr: Int
) : WebView(context, attrs, defStyleAttr) {
constructor(context: Context) : this(context, null) {}
constructor(context: Context, @Nullable attrs: AttributeSet?) : this(
context,
attrs,
0
)
init {
//修復(fù) WebView 初始化時會修改Activity 語種配置的問題
MultiLanguageUtil.updateLanguage(context)
}
}
項目中用這個WebView即可。這個問題在華為手機鴻蒙系統(tǒng)上會出現(xiàn)。
五、枚舉類的多語言實現(xiàn)
枚舉類型是線程安全的,并且只會裝載一次,這就導(dǎo)致下面的寫法導(dǎo)致枚舉的err值在切換語言后不會發(fā)生變化。
enum class Error( var code: Int, var err: String) {
/**
* 未知錯誤
*/
UNKNOWN(1000,appContext.getString(R.string.error_1000)),
/**
* 解析錯誤
*/
PARSE_ERROR(1001, appContext.getString(R.string.error_1001)),
/**
* 網(wǎng)絡(luò)錯誤
*/
NETWORK_ERROR(1002, appContext.getString(R.string.error_1002)),
/**
* 證書出錯
*/
SSL_ERROR(1004, appContext.getString(R.string.error_1004)),
/**
* 連接超時
*/
TIMEOUT_ERROR(1006, appContext.getString(R.string.error_1002));
fun getValue(): String {
return err
}
fun getKey(): Int {
return code
}
}
那么如果做枚舉類的多語言適配呢? 代碼如下:
enum class Error(private val code: Int, private val err: Int) {
/**
* 未知錯誤
*/
UNKNOWN(1000, R.string.error_1000),
/**
* 解析錯誤
*/
PARSE_ERROR(1001, R.string.error_1001),
/**
* 網(wǎng)絡(luò)錯誤
*/
NETWORK_ERROR(1002, R.string.error_1002),
/**
* 證書出錯
*/
SSL_ERROR(1004, R.string.error_1004),
/**
* 連接超時
*/
TIMEOUT_ERROR(1006, R.string.error_1002);
fun getValue(): String {
return appContext.getString(err)
}
fun getKey(): Int {
return code
}
}
因為字符串的id是固定的不會發(fā)生變化,所以即使枚舉類只會裝載一次也不會有影響,通過getValue就能取到正確語言的字符串。
參考
以上就是Android使用AndroidUtilCode實現(xiàn)多語言的詳細內(nèi)容,更多關(guān)于Android AndroidUtilCode多語言的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開發(fā)基礎(chǔ)實現(xiàn)最簡單的視頻播放示例
這篇文章主要為大家介紹了Android開發(fā)基礎(chǔ)實現(xiàn)最簡單的視頻播放示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
Android自動提示控件AutoCompleteTextView
這篇文章主要介紹了Android自動提示控件AutoCompleteTextView的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12
Android之PreferenceActivity應(yīng)用詳解(2)
看到很多書中都沒有對PreferenceActivity做介紹,而我正好又在項目中用到,所以就把自己的使用的在這總結(jié)一下,也方便日后查找2012-11-11
Android中使用TabHost 與 Fragment 制作頁面切換效果
這篇文章主要介紹了Android中使用TabHost 與 Fragment 制作頁面切換效果的相關(guān)資料,需要的朋友可以參考下2016-03-03

