android kotlin关于当前页面的strings.xml语言切换

1,595 阅读4分钟

废话不多说,主题:android kotlin关于当前页面的strings.xml语言切换

添加xml文件

首先设置需切换语言的控件,这里用一个TextView演示,控件的文本text属性需要引用strings.xml

    <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:gravity="center_horizontal"
       android:text="@string/test_settinglanguage"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@id/language_all"
   />

也可以在控件的文本text属性中先打上中文,例如“中文”,然后鼠标放在上面,再同时按下键盘“Alt+Shift+Enter”,进入Extract Resource弹出窗口

extract resource.jpg

点击“+”号,创建你想要添加的语言的文件夹,例如:“values”表示默认,“values-en”表示英语,“values-各国语言缩写”等,用于生成并放置你要用到的各种语言的strings.xml文件。

如上图所示,在“Resource name”中填写这个控件文本text属性的关键字。

然后,下面,将你想要添加进入的语言的文件夹都勾选上,点击确认。

这样,就会在你所有所选的文件夹里,生成同样内容的文件,即含有同样的关键字且内容相同。

之后,你需要,在保持关键字相同的情况下,根据文件夹对应的语言,翻译对应的内容

创建工具类Util文件

这个工具类里面的方法,会在很多地方要用到,所以推荐独立创建一个工具类,方便调用

每个方法的作用,已在下面代码中,以注释的形式解释

object LanguageUtil {

    // 该方法用于bnt或radioBnt随时切换语言时调用,无返回
    fun changeAppLanguage(context: Context, language: String){
        if (language == "") {
            return
        }
        val resources: Resources = context.resources
        val config: Configuration = resources.configuration
        // 获得屏幕参数:主要是分辨率,像素等。
        val dm: DisplayMetrics = resources.displayMetrics
        // 切换语言
        config.setLocale(getLocaleByLanguage(language));
        resources.updateConfiguration(config, dm);
    }

    // 根据想要的语言参数language,获取对应语言的Locale,更多语言请另行添加
    fun getLocaleByLanguage(language: String): Locale {
        var myLocale: Locale = Locale.CHINESE
        when {
            language.equals("en") -> {
                myLocale = Locale.ENGLISH
            }
            else -> {
                myLocale = Locale.CHINESE
            }
        }
        return myLocale
    }

    // 该方法为activity中的attachBaseContext提供继承内容,用于初始化切换语言
    fun attachBaseContext(context: Context, language: String): Context {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            updateResources(context, language)
        } else {
            return context
        }
    }

    // 该方法用于页面初始化时的切换语言,返回配置信息的上下文context
    @TargetApi(Build.VERSION_CODES.N)
    private fun updateResources(context: Context , language: String ) : Context {
        var resources :Resources = context.getResources()
        var locale: Locale = getLocaleByLanguage(language)
        var configuration: Configuration= resources.getConfiguration()
        configuration.setLocale(locale)
        configuration.setLocales(LocaleList(locale))
        return context.createConfigurationContext(configuration)
    }
}

修改Application类文件

需要在本项目中的applicaion里,添加注册Activity生命周期回调监听,用于项目的初始化

companion object {
    ... 
    //定义上下文单例
    var instance: Context by Delegates.notNull()
}

// 定义回调对象
private val callback = object : ActivityLifecycleCallbacks {
    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        Log.d("NullProblem", " ActivityLifecycleCallbacks -> onActivityCreated")
    }
    override fun onActivityStarted(activity: Activity) = Unit
    override fun onActivityResumed(activity: Activity) = Unit
    override fun onActivityPaused(activity: Activity) = Unit
    override fun onActivityStopped(activity: Activity) = Unit
    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit
    override fun onActivityDestroyed(activity: Activity) = Unit
}

override fun onCreate() {
    super.onCreate()
    ...
    instance = applicationContext
    // 注册Activity生命周期回调监听
    registerActivityLifecycleCallbacks(callback)
    /**
     * 对于7.0以下,需要在Application创建的时候进行语言切换
     */
    val language = ...    //这里,请读者使用SharePreference获取保存下来的语言设置
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
        LanguageUtil.changeAppLanguage(instance, language)
    }
}

注意,这里的language,请读者使用SharePreference获取保存下来的语言设置

例如:设置,唯一关键字A

这里将不再赘述SharePreference的使用方法。

修改语言设置页面Activity

重载attachBaseContext

attachBaseContext先于 onCreate()方法执行,用于语言显示的初始化。

/**
 * 此方法先于 onCreate()方法执行
 */
override fun attachBaseContext(context: Context) {
    // 这里,请读者使用SharePreference获取已保存的语言设置内容,关键字A,同上
    // 获取我们存储的语言环境,比如 "en","zh",等等
    val language = ...
    /**
     * attach对应语言环境下的context
     * 继承自LanguageUtil.attachBaseContext的方法,用于初始化语言设置
     */
    super.attachBaseContext(LanguageUtil.attachBaseContext(context, language))
}

在Botton的点击监听中,添加修改语言的方法

Btn.onClick {
    ...
    switchLanguage("en")
}

 创建修改语言的方法

// 根据不同国际语言xml,切换语言
private fun switchLanguage(language: String){

   // 如果是android 7.0及以上系统,直接把我们想要切换的语言类型保存在SharedPreferences中即可
   // 这里,请读者使用SharePreference保存要更改的语言内容,关键字A,同上
   // 类似putString("A", language), 详细SharePreference设置请读者另行查找解决方案

   // 如果是android 7.0以下,我们只需要调用changeAppLanguage方法即可
   if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
       LanguageUtil.changeAppLanguage(applicationContext, language);
   }

   // 结束当前页面,重启至首页,以刷新显示修改后的语言
   finish()
   val it = Intent(this, MainActivity::class.java)
   // 清空任务栈确保当前打开activit为前台任务栈栈顶
   // Intent.FLAG_ACTIVITY_CLEAR_TASK需搭配Intent.FLAG_ACTIVITY_NEW_TASK食用
   it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
   startActivity(it)
}

注意,这里android 7.0 以上的系统,需自行添加保存SharePreference的语言设置的代码,才能正常使用

至此,初步实现不同语言的strings.xml的切换了,比较简单,请读者不要放弃

后续将研究如何使整个项目同时切换语言。

csdn同一作者