Android

Android应用内无感知切换语言、修改应用字体不随系统大小改变

2022-09-20  本文已影响0人  码农修行之路

1. Utils

    /**
     * 重写attachBaseContext()-界面加载前,字体大小不随系统设置而变化,同时也更新一下语言
     * lan - zh、en等...
     */
    fun attachBaseContext(context: Context, fontScale: Float = 1f, lan: String): Context {
        val config: Configuration = context.resources.configuration
        config.setLocale(Locale(lan)) // 
        config.fontScale = fontScale
        return context.createConfigurationContext(config)
    }

    /**
     * 重写getResources()-界面加载前,字体大小不随系统设置而变化
     */
    fun getResources(context: Context, resources: Resources, fontScale: Float = 1f): Resources {
        val config: Configuration = resources.configuration
        return if (config.fontScale != fontScale) {
            config.fontScale = fontScale
            context.createConfigurationContext(config).resources
        } else {
            resources
        }
    }

    /**
     * 更新改变(locales、fontScale-setConfiguration)
     */
    private fun setSystemLanguage(context: Context, lan: String) {
        val resources = context.resources
        val config = resources.configuration
        config.setLocale(Locale(lan))
        // 更新资源触发attachBaseContext
        resources.updateConfiguration(config, resources.displayMetrics)
    }

    /**
     * 保存字体大小,后通知界面重建,它会触发attachBaseContext
     * 页面重新构建会白黑屏现象,所以修改语言界面,不执行该操作,需要主动更新当前页面资源,非栈顶页面可以调用
     */
    fun recreate(activity: Activity) {
        Handler(Looper.getMainLooper()).post {
            activity.recreate()
        }
    }

2. 基类 重写getResources()、attachBaseContext()方法

private var fontScale: Float = 1f
override fun getResources(): Resources {
    return Utils.getResources(this, super.getResources(), fontScale)
}
override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(
        Utils.attachBaseContext(
            newBase ?: applicationContext,
            fontScale
        )
    )
}

3. 切换语言界面,需要主动调用Utils.setSystemLanguage()方法,并更新控件资源

Utils.setSystemLanguage(App.instance)
// 动态刷新当前页面资源
Handler(Looper.getMainLooper()).post{
    App.instance.apply {
        titleView.setText(getString(R.string.language_settings))
        tvChinese.text = getString(R.string.chinese)
        tvEnglish.text = getString(R.string.english)
        btnSubmit.text = getString(R.string.confirm)
    }
}
// 然后通知根页面重新构建 根页面调用Utils.recreate()方法
上一篇下一篇

猜你喜欢

热点阅读