User16119012
User16119012

Reputation: 957

Android - Change app locale manually on button click

I want to change the application's Locale (language) to change programmatically when user wants to switch between Hindi and English using change language button.

I have a code to change language in place but it works only when I call in in the onCreate() of an activity before setContentView() method.

Any help is much appreciated.

Upvotes: 1

Views: 7579

Answers (4)

Dildarkhan Pathan
Dildarkhan Pathan

Reputation: 180

You can refresh activity as below sample to change user interface after updating locale language of app on click of button:

OnButtonClicked(){
//it will check for android version.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, language);
        } 
        return updateResourcesLegacy(context, language);
}
   //after setting language it will update ui
   refreshActivity();
}

public void refreshActivity() throws Exception {
    try {
        // refresh activity for language changes
        Intent intent = getIntent();
        YOUR_ACTIVITY_NAME.this.finish();
        System.out.println("activity finished");
        startActivity(intent);
        System.out.println("starting activity");
    } catch (Exception e) {
        Log.d("RegistrationForm", "application crashed...");
        e.printStackTrace();
    }
}




@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

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


    context.getResources().updateConfiguration(configuration,
            context.getResources().getDisplayMetrics());

    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Resources resources = context.getResources();

    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        configuration.setLayoutDirection(locale);
    }

    resources.updateConfiguration(configuration, resources.getDisplayMetrics());

    return context;
}

Complete Steps:

  1. On button click check Android Version if Android version is below N then it will execute legacy code for locale language change that is updateResourcesLegacy. Else if Android Version is N or above N then it will execute updateResources() method.

  2. After setting language refresh activity by calling refreshActivity() method, this method will update the user interface.

Upvotes: 1

Arjun saini
Arjun saini

Reputation: 4182

See here my answer

Android Font in more then one langauge on single screen

for example if you want your application to support both English and Arabic strings (in addition to the default strings), you can simply create two additional resource directories called /res/values-en (for the English strings.xml) and /res/values-ar (for the Arabic strings.xml).

Within the strings.xml files, the resource names are the same.

For example, the /res/values-en/strings.xml file could look like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello in English!</string>
</resources>

Whereas, the /res/values-ar/strings.xml file would look like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">مرحبا في اللغة الإنجليزية</string>
</resources>

also , the /res/values-ur_IN/strings.xml file would look like this for urdu:

ur_IN for india ur_PK for pakisthan

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">انگریزی میں خوش!!</string>
</resources>

A default layout file in the /res/layout directory that displays the string refers to the string by the variable name @string/hello, without regard to which language or directory the string resource is in.

The Android operating system determines which version of the string (French, English, or default) to load at runtime.A layout with a TextView control to display the string might look like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="@string/hello" >
</LinearLayout>

The string is accessed programmatically in the normal way:

String str = getString(R.string.hello);

For change the language you need to like that change lang..

btn_english.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Locale locale = new Locale("en"); 
                  Locale.setDefault(locale);
                  Configuration config = new Configuration();
                  config.locale = locale;
                  getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
                  Toast.makeText(this, getResources().getString(R.string.lbl_langSelectEnglis), Toast.LENGTH_SHORT).show();

            }
        });



 btn_arbice.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                 Locale locale = new Locale("ar"); 
                  Locale.setDefault(locale);
                  Configuration config = new Configuration();
                  config.locale = locale;
                  getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
                  Toast.makeText(this, getResources().getString(R.string.lbl_langSelecURdu), Toast.LENGTH_SHORT).show();

            }
        });


 btn_urdu.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Locale locale = new Locale("ur_IN"); 
                  Locale.setDefault(locale);
                  Configuration config = new Configuration();
                  config.locale = locale;
                  getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
                  Toast.makeText(HomeActivity.this, getResources().getString(R.string.lbl_langSelectEnglis), Toast.LENGTH_SHORT).show();

            }
        });

Upvotes: 6

Nikesh Maharjan
Nikesh Maharjan

Reputation: 183

Use SharedPrefrences to save the user prefrences and call locale in onStart() not on onCreate(). This worked fine for me Define DEFAULT value, so that your app wont cash

public static final String Default="en"; //so if value isn't found then english language will be used.


protected void onStart() {
    SharedPreferences sharedPreferences = this.getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
    String pine = sharedPreferences.getString("language", DEFAULT);
    String languageToLoad = pine;
    Locale locale = new Locale(languageToLoad);//Set Selected Locale
    Locale.setDefault(locale);//set new locale as default
    Configuration config = new Configuration();//get Configuration
    config.locale = locale;//set config locale as selected locale
    this.getResources().updateConfiguration(config, this.getResources().getDisplayMetrics());
    invalidateOptionsMenu();
    setTitle(R.string.app_name);
    super.onStart();
}

Where I set sharedPrefrences value to hindi or english as per user choice. I used switch in this case. below you can see code.

aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

            if (aSwitch.isChecked()) {
                SharedPreferences hisharedPreferences = getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
                SharedPreferences.Editor hieditor = npsharedPreferences.edit();
                npeditor.putString("language","hi");
                npeditor.commit();
                aSwitch.setChecked(true);
                Toast.makeText(Settings.this, "Hindi Language Selected", Toast.LENGTH_LONG).show();

            } else {
                SharedPreferences ensharedPreferences = getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
                SharedPreferences.Editor eneditor = ensharedPreferences.edit();
                eneditor.putString("language","en");
                eneditor.commit();
                Toast.makeText(Settings.this, "English Language Selected", Toast.LENGTH_LONG).show();
                aSwitch.setChecked(false);
            }
        }
    });

Hope this helped!! Feel free to ask me if you got stuck in any step!!

Upvotes: 1

K.Sopheak
K.Sopheak

Reputation: 23144

Try this function when click button.

public void changeLocale()
{
        Resources res = getResources();
        // Change locale settings in the app.
        DisplayMetrics dm = res.getDisplayMetrics();
        android.content.res.Configuration conf = res.getConfiguration();
        conf.locale = new Locale("hi_IN");
        res.updateConfiguration(conf, dm);

        setContentView(R.layout.xxx);
}

Upvotes: 2

Related Questions