5

I want to write a application that can display either english or chinese. I have already prepared 2 string.xml which is value/strings.xml and value-zh-rHK/strings.xml. But I have no idea how to change the language via ListPreference of android.

xml/preferences.xml:

<?xml version="1.0" encoding="utf-8"?>

<SwitchPreference
    android:key="pref_nightmode"
    android:title="@string/nightmode"
    android:defaultValue="false">
</SwitchPreference>

<ListPreference
    android:key="pref_lang"
    android:title="@string/lang"
    android:dialogTitle="Choose Language"
    android:entries="@array/lang"
    android:entryValues="@array/lang_value"
    android:defaultValue="@string/lang_default">
</ListPreference>

and the Preferences.java

public class Preferences extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setTitle(drawer_menu[5]);
    getFragmentManager().beginTransaction().replace(R.id.content_frame, new MainPreferenceFragment()).commit();
}

public static class MainPreferenceFragment extends PreferenceFragment {
    String locale;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        PreferenceManager pm = getPreferenceManager();
        ListPreference lang = (ListPreference) pm.findPreference("pref_lang");
        if(lang.getValue().equals("English")) {
            locale = "en_US";
        } else {
            locale = "zh_HK";
        }
    }
}

The activity extends BaseActivity because I have a drawer menu right there.

Veve
  • 6,385
  • 5
  • 41
  • 57
rascee
  • 61
  • 1
  • 1
  • 8

1 Answers1

10

You can change language settings for app only. Use Locale class and update default configuration. Language change only applied when activity restart or re-start application. Use following locale class

public class LocaleUtils {

    private static Locale sLocale;

    public static void setLocale(Locale locale) {
        sLocale = locale;
        if(sLocale != null) {
            Locale.setDefault(sLocale);
        }
    }

    public static void updateConfig(ContextThemeWrapper wrapper) {
        if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Configuration configuration = new Configuration();
            configuration.setLocale(sLocale);
            wrapper.applyOverrideConfiguration(configuration);
        }
    }

    public static void updateConfig(Application app, Configuration configuration) {
        if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            //Wrapping the configuration to avoid Activity endless loop
            Configuration config = new Configuration(configuration);
            config.locale = sLocale;
            Resources res = app.getBaseContext().getResources();
            res.updateConfiguration(config, res.getDisplayMetrics());
        }
    }
}

Application class :

public class App extends Application {
    public void onCreate(){
        super.onCreate();
        // get user preferred language set locale accordingly new locale(language,country)
        LocaleUtils.setLocale(new Locale("iw"));
        LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        LocaleUtils.updateConfig(this, newConfig);
    }
}

BaseActivity :

public class BaseActivity extends Activity {
    public BaseActivity() {
        LocaleUtils.updateConfig(this);
    }
}

Above answer is taken from : Changing Locale within the app itself

Android Document : http://developer.android.com/reference/java/util/Locale.html

Community
  • 1
  • 1
USKMobility
  • 6,044
  • 2
  • 25
  • 33
  • That means I don't need to do this in preference? I can code in normal class but use the above method? – rascee Apr 28 '16 at 18:15
  • You should use preference to save user preference. Get value from preference and update locale according in application class. – USKMobility Apr 28 '16 at 18:23
  • after setLocale how to refresh the view? – WolfJee Nov 02 '16 at 11:18
  • You need to restart your activity or kill your app to take effect of locale, for more details http://stackoverflow.com/documentation/android/3345/localization-with-resources-in-android#t=20161102122845725949 – USKMobility Nov 02 '16 at 12:29