3

I have 2 string files "en" and "es". When ever I am changing the locale in locale manager class, it saves the new locale successfully but does not reflect changes on refreshing activity.

MyApplication.kt

open class MyApplication : Application() {

    init {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(LocaleManagerMew.setLocale(base))
       // MultiDex.install(base)
    }

    override fun onCreate() {
        super.onCreate()

    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        LocaleManagerMew.setLocale(this)
        Log.d("app", "onConfigurationChanged: " + newConfig.locale.getLanguage())
    }
}

LocaleManagerNew.kt

object LocaleManagerMew {

    val SELECTED_LANGUAGE = "MEW_CURRENT_-- USER_LANGUAGE"
    var mSharedPreference: SharedPref? = null

    var mEnglishFlag = "en"
    var mSpanishFlag = "es"

    fun setLocale(context: Context?): Context {
        return updateResources(context!!, getCurrentLanguage(context)!!)
    }

    inline fun setNewLocale(context: Context, language: String) {

        persistLanguagePreference(context, language)
        updateResources(context, language)
    }

    inline fun getCurrentLanguage(context: Context?): String? {

        var mCurrentLanguage: String?

        if (mSharedPreference == null)
            mSharedPreference = SharedPref(context!!)

        mCurrentLanguage = mSharedPreference!!.getSavedLang()

        return mCurrentLanguage
    }

    fun persistLanguagePreference(context: Context, language: String) {
        if (mSharedPreference == null)
            mSharedPreference = SharedPref(context!!)

        mSharedPreference!!.setSavedLang(language)

    }

    fun updateResources(context: Context, language: String): Context {

        var contextFun = context

        var locale = Locale(language)
        Locale.setDefault(locale)

        var resources = context.resources
        var configuration = Configuration(resources.configuration)

        if (Build.VERSION.SDK_INT >= 17) {
            configuration.setLocale(locale)
            contextFun = context.createConfigurationContext(configuration)
        } else {
            configuration.locale = locale
            resources.updateConfiguration(configuration, resources.getDisplayMetrics())
        }
        return contextFun
    }
}

BaseActivity.kt

override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(LocaleManagerMew.setLocale(base))
    }

MainActivity.kt

 R.id.spanishCL ->  {
                sp.setSavedLang("es")
                var mCurrentLanguage = LocaleManagerMew.getCurrentLanguage(this@MainActivity.applicationContext)
                LocaleManagerMew.setNewLocale(this@MainActivity, LocaleManagerMew.mSpanishFlag)
               mContext?.recreate()

            }

This is the onClick method call to change english locale to spanish. After recreating acitivity new locale changes does not reflect

Kartika Vij
  • 493
  • 2
  • 4
  • 18

1 Answers1

2

Try the below code for updating language from attachBaseContext of every Activity

    fun setLanguage(context: Context, language: String): ContextWrapper {
        var mContext = context

        val localeLang = language.split("_".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        val locale: Locale
        if (localeLang.size > 1)
            locale = Locale(localeLang[0], localeLang[1])
        else
            locale = Locale(localeLang[0])

        val res = mContext.resources
        val configuration = res.configuration

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            val localeList = LocaleList(locale)
            LocaleList.setDefault(localeList)
            configuration.locales = localeList
            mContext = mContext.createConfigurationContext(configuration)
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            configuration.setLocale(locale)
            mContext = mContext.createConfigurationContext(configuration)
        } else {
            configuration.locale = locale
            res.updateConfiguration(configuration, res.getDisplayMetrics())
        }

        return ContextWrapper(mContext)
    }

And implementation in attachBaseContext of Activity class

//    For Language Changing
override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(newBase?.let {
        Common.setLanguage(
            it,
            PreferenceManager.getPref<String>(Constants.LANGUAGE_PREFERENCE).toString()
        )
    })
}

And this is how I restart the activity from fragment

Handler().post {
            val intent = activity?.intent
            intent?.flags =
                Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK or
                        Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NO_ANIMATION
            activity?.overridePendingTransition(0, 0)
            activity?.finish()

            activity?.overridePendingTransition(0, 0)
            startActivity(intent)
        }
Kartik
  • 709
  • 1
  • 9
  • 21
  • Have you tried this? because you are trying to assign a value in a val i.e configuration.locales – Kartika Vij Nov 18 '19 at 08:02
  • Yes I have tried and implemented this in my code and its working fine for me – Kartik Nov 18 '19 at 09:26
  • but I am getting error that val i.e configuration.locales can not be re-assigned – Kartika Vij Nov 18 '19 at 09:43
  • This is strange as I am not throwing any errors in my code – Kartik Nov 18 '19 at 11:25
  • @kartikavij check the updated answer for implementation. I've added this function inside the Common class – Kartik Nov 18 '19 at 12:41
  • I have no idea, how it is working at your end because this is not at all reflecting any changes at my end – Kartika Vij Nov 19 '19 at 06:27
  • I see you are updating the language from the Application class. You must update the language from `attachBaseContext` method of every activity – Kartik Nov 19 '19 at 06:58
  • I have tried that too, but no changes... code is working fine in java but not in kotlin. – Kartika Vij Nov 19 '19 at 07:01
  • Have you added translations for every string added in `strings.xml` for en and es? – Kartik Nov 19 '19 at 07:09
  • yes i have added every string in strings file for en and es – Kartika Vij Nov 19 '19 at 08:45
  • Try making a demo application with the same code by adding 1 or 2 textViews and changeLanguage button and a single activity in Kotlin and see if the issue persists. Maybe there may be something wrong with the code in your project. – Kartik Nov 19 '19 at 10:06