Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Locale: onConfigurationChanged not called

I want my language to change dynamically and I am trying to use onConfigurationChanged but it is not being called. I have a MainActivity that creates my action bar and viewpager. The rest of my pages are Fragments. In my SettingsFragment I have a button to switch the language to French.

langChange.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View vi) {
            MainActivity main = (MainActivity)getActivity();
            main.langChange();
        }

});

Then in my MainActivity I have

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    if (locale != null){
        newConfig.locale = locale;
        Locale.setDefault(locale);
        getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
    }
}

public void langChange(){
    if(currentLanguage == FRENCH_LANGUAGE){
        locale = new Locale("en");
        Locale.setDefault(locale);
        Configuration c = getBaseContext().getResources().getConfiguration();
        c.locale = locale;
        getBaseContext().getResources().updateConfiguration(c,getBaseContext().getResources().getDisplayMetrics());
        currentLanguage = "English";
    }
    else if(currentLanguage == ENGLISH_LANGUAGE){
        locale = new Locale("fr");
        Locale.setDefault(locale);
        Configuration c = getBaseContext().getResources().getConfiguration();
        c.locale = locale;
        getBaseContext().getResources().updateConfiguration(c,getBaseContext().getResources().getDisplayMetrics());
        currentLanguage = "French";
    }
    actionBar.setSelectedNavigationItem(actionBar.getTabCount() - 1); //This just puts it back to the settings tab
}

The onConfigurationChanged is not being called. In my manifest I have:

<activity android:name="MainActivity" android:screenOrientation="portrait" android:configChanges="locale"></activity>

I have tried adding one or all of these options orientation|keyboardHidden|screenSize with no success.

The reason for all of this is because I want to change the actionBar text and all the other text once I click the button. I have a separate strings file for French.

Any help would be great.

like image 686
BigT Avatar asked Aug 21 '13 18:08

BigT


2 Answers

You have to define android:configChanges="layoutDirection|locale" in order for onConfigurationChanged() to be called.

like image 158
Alex.F Avatar answered Oct 01 '22 17:10

Alex.F


Ok, I've looked into this a bit.

I'm not sure, why the onConfigurationChanged method isn't called, so I'm hoping someone can enlighten us on this part.

In my search I stumbled upon this tutorial , which actually change the Locale, by changing the configuration.

Your code looks a lot like this tutorial actually ;-)

Anyways, the important thing about the tutorial and the code is this method:

private void updateTexts() {
    txt_hello.setText(R.string.hello_world);
    btn_en.setText(R.string.btn_en);
    btn_ru.setText(R.string.btn_ru);
    btn_fr.setText(R.string.btn_fr);
    btn_de.setText(R.string.btn_de);
}

This is where the "magic" happens; after you've changed your locale you will need to reload your resources and since you told Android you want to handle some configurations on your own you need to specifically reload all your text, by setting your UI items texts again.

When this is done, the app will load the strings from the specific locales folder.

The answer to why Android behaves this way, can be found in the official documentation for the Activity saying:

[...]

This is done because any application resource, including layout files, can change based on any configuration value. Thus the only safe way to handle a configuration change is to re-retrieve all resources, including layouts, drawables, and strings. Because activities must already know how to save their state and re-create themselves from that state, this is a convenient way to have an activity restart itself with a new configuration.

The guy writing the tutorial was kind enough to add the whole tutorial project as a download, so I recommend you go check it out to see how it's working, because it is working ;-) You can outcomment the onConfigurationChanged method, as it doesn't seem to be doing anything.

Hope this helps.

like image 21
Darwind Avatar answered Oct 01 '22 17:10

Darwind