Change Locale not work after migrate to Androidx

2019-06-20 07:36发布

问题:

I have an old project that support multi languages. I want to upgrade support library and target platform, Before migrate to Androidx every things work fine but now change language not work!

I use this code to change default locale of App

private static Context updateResources(Context context, String language)
{
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);

    return context.createConfigurationContext(configuration);
}

And call this method on each activity by override attachBaseContext like this:

@Override
protected void attachBaseContext(Context newBase)
{
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    String language = preferences.getString(SELECTED_LANGUAGE, "fa");
    super.attachBaseContext(updateResources(newBase, language));
}

I try other method to get string and I noticed that ‍‍‍‍getActivity().getBaseContext().getString work and getActivity().getString not work. Even the following code does not work and always show app_name vlaue in default resource string.xml.

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/app_name"/>

I share a sample code in https://github.com/Freydoonk/LanguageTest

Also getActivity()..getResources().getIdentifier not work and always return 0!

回答1:

Finally I find the problem in my app. When migrate the project to Androidx dependencies of my project changed like this:

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.1.0-alpha04'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02'
} 

As it is seen, version of androidx.appcompat:appcompat is 1.1.0-alpha03 when I changed it to the latest stable version, 1.0.2, my problem is resolved and the change language working properly.

I find the latest stable version of appcompat library in Maven Repository. I also change other libraries to latest stable version.

Now my app dependencies section is like bellow:

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.0.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}


回答2:

1. Method you may use in attachBaseContext()

private void setLanguage(Context mContext, String localeName) {
        Locale myLocale = new Locale(localeName);
        Resources res = mContext.getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        conf.locale = myLocale;
        res.updateConfiguration(conf, dm);
    }

2. Override in activities

@Override
protected void attachBaseContext(Context newBase) {
    setLanguage(newBase, "your language");
    super.attachBaseContext(newBase);
}

NB: This is working fine for me after I recreate the activity



回答3:

Now there is a newer version that also works:

implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'

As @Fred mentioned appcompat:1.1.0-alpha03 has a glitch although it's not mentioned on their release versions log