【问题标题】:Android Kotlin LocalizationAndroid Kotlin 本地化
【发布时间】:2021-07-11 07:33:11
【问题描述】:

我正在我的android项目中实现本地化。我已经实现了依赖注入,因此代码看起来更干净,并且每个类在本地化实现过程中都有自己的小功能。

问题: 在应用程序第一次启动时,应用程序使用我手机的本地化 (en-GB),在我更改语言后,应用程序成功更改配置并重新创建其活动,并使用我想要的 strings.xml 文件(在这种情况下是 values-de 文件夹中的字符串)。一切正常,即使我退出应用程序并返回应用程序,本地化也是我设置的。唯一的问题是,当我强制关闭应用程序并再次打开它时。它显示了原始 values/strings.xml 文件中的字符串,即使在我正常工作时使用的每种方法中都设置了另一种语言的参数(通过调试检查)。

App.kt 在清单中被引用,strings.xml 文件都被翻译,LocaleHelper.kt 成功地将上下文返回给应用程序,其中包含从 SharedPreferences 检索到的新本地化。

LocaleHelper.kt

object LocaleHelper {

     const val SELECTED_LANGUAGE = "Locale.Helper.Selected.Language"

    fun onAttach(context: Context): Context {
        val locale = getLocale(context)
        return setLocale(context, locale)
    }

    private fun getLocale(context: Context): Locale {
        return load(context)
    }

    fun setLocale(context: Context, locale: Locale): Context {
        persist(context, locale)

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            updateResources(context, locale)
        } else
            updateResourcesLegacy(context, locale)
    }

    fun isRTL(locale: Locale): Boolean {
        return Locales.RTL.contains(locale.language)
    }

    private fun getPreferences(context: Context): SharedPreferences {
        return context.getSharedPreferences(LocaleHelper::class.java.name, Context.MODE_PRIVATE)
    }

    private fun persist(context: Context, locale: Locale?) {
        if (locale == null) return
        getPreferences(context)
            .edit()
            .putString(SELECTED_LANGUAGE, locale.language)
            .apply()
    }

    private fun load(context: Context): Locale {
        val preferences = getPreferences(context)
        val language = preferences.getString(SELECTED_LANGUAGE, Locale.getDefault().language)
        return Locale(language!!)
    }

    @TargetApi(Build.VERSION_CODES.N)
    private fun updateResources(context: Context, locale: Locale): Context {

        Locale.setDefault(locale)

        val configuration = context.resources.configuration

        configuration.setLocale(locale)

        configuration.setLayoutDirection(locale)

        return context.createConfigurationContext(configuration)
    }


    @SuppressWarnings("deprecation")
    private fun updateResourcesLegacy(context: Context, locale: Locale): Context {
        Locale.setDefault(locale)

        val resources = context.resources

        val configuration = resources.configuration

        configuration.locale = locale

        configuration.setLayoutDirection(locale)

        resources.updateConfiguration(configuration, resources.displayMetrics)

        return context
    }

}

LocaleHelperActivityDelegate.kt 和 LocaleHelperActivityDelegateImpl.kt

interface LocaleHelperActivityDelegate {
    fun setLocale(activity: Activity, newLocale: Locale)
    fun setWelcomeActivityLocale(activity: Activity, newLocale: Locale)
    fun attachBaseContext(newBase: Context): Context
    fun onPaused()
    fun onResumed(activity: Activity)
    fun onCreate(activity: Activity)
}

class LocaleHelperActivityDelegateImpl : LocaleHelperActivityDelegate {

    val KEY_ACTIVITY_LOCALE_CHANGED = "activity_locale_changed"

    override fun onCreate(activity: Activity) {
        activity.window.decorView.layoutDirection =
                if (LocaleHelper.isRTL(Locale.getDefault())) View.LAYOUT_DIRECTION_RTL else View.LAYOUT_DIRECTION_LTR
    }

     var locale: Locale = Locale.getDefault()

    override fun setLocale(activity: Activity, newLocale: Locale) {
        LocaleHelper.setLocale(activity, newLocale)

        locale = newLocale

        activity.startActivity(activity.intent)

        activity.overridePendingTransition(0, 0)

        activity.intent.putExtra(KEY_ACTIVITY_LOCALE_CHANGED, true)

        activity.finish()

        activity.overridePendingTransition(0, 0)

    }

    override fun setWelcomeActivityLocale(activity: Activity, newLocale: Locale) {
        LocaleHelper.setLocale(activity, newLocale)

        locale = newLocale

        activity.startActivity(activity.intent)

        activity.overridePendingTransition(0, 0)

        activity.intent.putExtra(KEY_ACTIVITY_LOCALE_CHANGED, true)

        activity.finish()

        activity.overridePendingTransition(0, 0)
    }

    override fun attachBaseContext(newBase: Context): Context {
        return LocaleHelper.onAttach(newBase)
    }


    override fun onPaused() {
        locale = Locale.getDefault()
    }



    override fun onResumed(activity: Activity) {

        val localeDefault = Locale.getDefault()

        val isLocaleChanged = activity.intent.getBooleanExtra(KEY_ACTIVITY_LOCALE_CHANGED, false)

        if(isLocaleChanged) {
            activity.startActivity(activity.parentActivityIntent)
            activity.overridePendingTransition(0, 0)

            activity.finish()
            activity.overridePendingTransition(0, 0)
        }
    }
}

class LocaleHelperApplicationDelegate {
    fun attachBaseContext(base: Context): Context {
        return LocaleHelper.onAttach(base)
    }

    fun onConfigurationChanged(context: Context) {
        LocaleHelper.onAttach(context)
    }
}

LocaleAwareCompatActivity.kt

open class LocaleAwareCompatActivity : AppCompatActivity() {
    private val localeDelegate = LocaleHelperActivityDelegateImpl()

    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(localeDelegate.attachBaseContext(newBase))
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        localeDelegate.onCreate(this)
    }

    override fun onResume() {
        super.onResume()
        localeDelegate.onResumed(this)
    }

    override fun onPause() {
        super.onPause()
        localeDelegate.onPaused()
    }

    open fun updateLocale(locale: Locale) {
        localeDelegate.setLocale(this, locale)
    }
}

BaseActivity.kt,在项目的每个Activity类中实现

open class BaseActivity : AppCompatActivity() {
    private val localeDelegate = LocaleHelperActivityDelegateImpl()

    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(localeDelegate.attachBaseContext(newBase))
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        localeDelegate.onCreate(this)
    }

    override fun onResume() {
        super.onResume()
        localeDelegate.onResumed(this)
    }


    override fun onPause() {
        super.onPause()
        localeDelegate.onPaused()
    }

    open fun updateLocale(locale: Locale) {
        localeDelegate.setLocale(this, locale)
    }

    override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
        super.applyOverrideConfiguration(overrideConfiguration)
    }

    open fun updateWelcomeActivityLocale(locale: Locale)
    {
        localeDelegate.setWelcomeActivityLocale(this, locale)
    }
}

还有我实现应用程序的 App 类

class App : Application()
{


    private val localeAppDelegate = LocaleHelperApplicationDelegate()


    override fun onCreate() {
        super.onCreate()

        // Unique initialization of Cache library to allow saving into device
        CacheLibrary.init(this)

        // Unique initialization of Dependency Injection library to allow the use of application context
        startKoin { androidContext(this@App) }

        Preferences.init(this)

    }

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(localeAppDelegate.attachBaseContext(base))
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        localeAppDelegate.onConfigurationChanged(this)
    }

【问题讨论】:

    标签: android kotlin configuration localization


    【解决方案1】:

    您可以通过使用此库来避免上述所有代码。它很简单,可以完成所有工作

    Lingver

    在 Application.onCreate 中初始化库

    Lingver.init(context, defaultLanguage)
    

    例如,从您的设置屏幕更改区域设置:

     Lingver.getInstance().setLocale(context, language)
    

    【讨论】:

    • 我可以在没有重启活动的情况下使用 lingver 吗?
    • 是的,您无需重新启动活动即可使用它
    • 不工作,设置区域设置后语言没有改变
    • 你初始化库了吗
    • 是的,我在应用程序中初始化,并在更改语言时使用 setlocale,但如果没有重新创建功能,它什么也不做
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多