• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Android-国际化之多语言适配小记

android 搞代码 3年前 (2022-03-01) 27次浏览 已收录 0个评论

害,乱哄哄,总要去梳理.

面对未知的所有,陌生感突突的.

甲方要求实现 App 国际化多语言,正好抽个工夫弄了下,害,被本人蠢到死,特意记录下.

如有不对,欢送斧正,一起交换~

成果演示

视频录制的不是太好,整体的成果进去了,大家见谅~

版本为别为: 6.0、8.0 以及 10.0

搞起来

简略说下须要留神的:

  • 国际化,多语言目录创立,资源配置;
  • Locale 资源获取以及本地缓存,缓存的目标是为了下次从新关上 App 仍然是上次抉择的语言;
  • Android 零碎间不同的差别,例如 7.0 后不再是惟一默认语言,而是多种语言配置,具体差异如下所示:

好啦,间接上码~

网上看到大家再探讨这个 androidx 包下 appcompat 问题,这里也把我应用的版本贴出来:

  • implementation ‘androidx.appcompat:appcompat:1.2.0’

一、创立对应的资源文件

形式有两种.如下:

  • 形式一:

右键 「res」,抉择 「New」,「Android Resource File」:

按如下图进行抉择配置语言表:

  • 形式二:

Android Studio 左侧抉择「Resource Manager」,随后抉择小地图 + 的标记,最初在列表中抉择对应兼容的国家即可.

随后会为咱们创立抉择的国家的 values 目录以及 strings 文件,如下所示:

好了,到当初,根本的语言目录以及文件都曾经创立好了,剩下的就是会有专人负责提供对应的翻译词.

当然,我司一贯的准则是,本人入手,饥寒交迫.

提供了局部罕用的、不错的在线翻译地址,如下:

二、贴心附上过程中应用的 MMKV Utils

记得去援用 MMKV 依赖以及初始化,地址如下:

集体应用的版本如下:

  • implementation ‘com.tencent:mmkv:1.0.17’
/**
 * @author:HLQ_Struggle
 * @date:2020/4/13
 * @desc:根底数据缓存
 */

class MMKVPro<T>(
    private val mmkv: MMKV,
    private val key: String,
    private val defValue: T
) {

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
        // 本地加密存储并反对多过程拜访
        return mmkv.run {
            when (defValue) {
                is String -> getString(key, defValue)
                is Boolean -> getBoolean(key, defValue)
                is Long -> getLong(key, defValue)
                is Int -> getInt(key, defValue)
                is Float -> getFloat(key, defValue)
                else -> Unit
            }
        } as T
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        return mmkv.run {
            when (value) {
                is String -> putString(key, value)
                is Boolean -> putBoolean(key, value)
                is Long -> putLong(key, value)
                is Int -> putInt(key, value)
                is Float -> putFloat(key, value)
                else -> Unit
            }
        }
    }

}

/**
 * 移除 key
 */
fun removeKey(key: String) {
    MMKV.mmkvWithID(F_APP_CACHE, MMKV.MULTI_PROCESS_MODE, K_ENCRYPT).run {
        remove(key)
    }
}

三、筹备多语言 utils

/**
 * @author HLQ_Struggle
 * @date 2021/02/26
 * @desc
 */

/**
 * Activity 更新语言资源
 */
fun getAttachBaseContext(context: Context): Context {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return setAppLanguageApi24(context)
    } else {
        setAppLanguage(context)
    }
    return context
}

/**
 * 设置利用语言
 */
@Suppress("DEPRECATION")
fun setAppLanguage(context: Context) {
    val resources = context.resources
    val displayMetrics = resources.displayMetrics
    val configuration = resources.configuration
    // 获取以后零碎语言,默认设置追随零碎
    val locale = getAppLocale()
    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)
private fun setAppLanguageApi24(context: Context): Context {
    val locale = getAppLocale()
    val resource = context.resources
    val configuration = resource.configuration
    configuration.setLocale(locale)
    configuration.setLocales(LocaleList(locale))
    return context.createConfigurationContext(configuration)
}

/**
 * 获取 App 以后语言
 */
private fun getAppLocale() = when (LocalDataStorage().multilingual) {
    0 -> { // 追随零碎
        getSystemLocale()
    }
    1 -> { // 中文
        Locale.CHINA
    }
    2 -> { // 英文
        Locale.ENGLISH
    }
    else -> Locale.ENGLISH
}

/**
 * 获取以后零碎语言,如未蕴含则默认英文
 */
private fun getSystemLocale(): Locale {
    val systemLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        LocaleList.getDefault()[0]
    } else {
        Locale.getDefault()
    }
    return when (systemLocale.language) {
        Locale.CHINA.language -> {
            Locale.CHINA
        }
        Locale.ENGLISH.language -> {
            Locale.ENGLISH
        }
        else -> {
            Locale.ENGLISH
        }
    }
}

四、在抉择多语言页面进行解决

当然这里我的思路是,本地缓存语言列表索引,而后后续依据 id 间接获取对应的语言即可.

点击确认时,进行缓存以后抉择的

override fun onClick(v: View?) {
    when (v?.id) {
        R.id.tvDone -> {
            // 更新抉择状态
            LocalDataStorage().multilingual = mAfterPosition
            setAppLanguage(this)
            reStartActivity()
        }
    }
}

private fun reStartActivity() {
    val intent = Intent(mSelfActivity, MainActivity::class.java)
    intent.flags = FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    startActivity(intent)
    // 勾销其专场动画
    overridePendingTransition(0, 0)
}

五、Application 中 Configuration 解决

override fun onConfigurationChanged(newConfig: Configuration?) {
    super.onConfigurationChanged(newConfig)
    // ...
    setAppLanguage(this)
}

六、BaseActivity 解决

因为须要重建 Activity 去解决对应资源,所以这里集体是把它放在 BaseActivity 中去解决:

override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(newBase?.let { getAttachBaseContext(it) })
}

七、优化项,资源文件更新

大家千万记得更新这个,如果做过 Apk 大小优化,八成都会限度 resConfigs 内容,防止打包时多处一些无用内容减少 Apk 大小.
大家千万记得更新这个,如果做过 Apk 大小优化,八成都会限度 resConfigs 内容,防止打包时多处一些无用内容减少 Apk 大小.
大家千万记得更新这个,如果做过 Apk 大小优化,八成都会限度 resConfigs 内容,防止打包时多处一些无用内容减少 Apk 大小.

我就是写完之后,怎么也不出成果,起初一看,好家伙,限度只有中文.过后的难堪、无奈…

resConfigs "zh-rCN", "en"

好了,到此结束,当然,Android 不得不面对的多机型适配…

这里后续遇到在更新把~

多语言遇到的一些问题

1. 布局问题

这个确实让人蛮头疼的,尤其对于咱们基建不残缺的状况,能做的只能说是保障大部分的成果,尽量应用短称英文或者非中文.

同时这个也揭示我,如何在开发的过程中尽可能兼容后续呢?

可能也是教训把,缓缓致力.

2.TabLayout 英文模式下大写

切换后成果如下:

目前应用的 TabLayout 版本如下:

  • implementation ‘com.google.android.material:material:1.2.1’

喏,设置个款式就好:

<style name="TabLayoutTextStyle" parent="TextAppearance.Design.Tab">
    <item name="android:textSize">@dimen/sp_18</item>
    <item name="textAllCaps">false</item>
</style>

后续遇到再补充吧.

参考资料

  • 本地化您的利用
  • Unicode 和国际化反对
  • 语言和语言区域解析概览
  • Android(国际化)多语言的实现和切换
  • Android多语言切换(兼容安卓9、10)

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Android-国际化之多语言适配小记

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址