Reputation: 2851
How do I implement language switching without having to manually set locale inside an Android app? I know the app will load the strings.xml according to locale during startup, but I don't want this choice to be made based on system locale, but instead to be user-specified in Settings.
Or, is manually setting locale fine?
Upvotes: 12
Views: 12645
Reputation: 1
Ok. Let's do the easy way. In Your Layout folder, do 2 copies of xml layouts. Name one of them main.xml (your local language) and the other one mainen.xml for english. In the values folder, the strings.xml file contains also two lines of text for both of the languages: <string name="hello">Tere, Maailm!</string>
for local language and <string name="hello_en">Hello World!</string>
for english language. Going back to the xml layouts, the main.xml contains android:text="@string/hello"
for your text and the second duplicate mainen.xml contains all the same layout and the strings with the slight difference of retrieving the english version of the line of text from the strings.xml file: android:text="@string/hello_en"
. And programmatically, to set the title when needed and to specify in the beginning of each activity, which layout to choose, use a global variable languageToLoad, that has been declared and instantiated in your first (starting) class: protected static boolean languageToLoad = true;
,
in that same class the onCreate method should contain some radio buttons (You need to define and name them in corresponding layout xml also): `
// ...
View radio1 = findViewById(R.id.Et);
radio1.setOnClickListener(this);
View radio2 = findViewById(R.id.En);
radio2.setOnClickListener(this);
// ...`
And later in the class:`
// ...
public void onClick(View v1) {
switch (v1.getId()) {
case R.id.Et:
languageToLoad = true;
break;
case R.id.En:
languageToLoad = false;
break;
// ...`
And later in the program, in the onCreate method of your different activities:`
//...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (YourSuperClass.languageToLoad) {
setContentView(R.layout.youractivity); // estonian
setTitle(R.string.youractivity_title);
} else {
setContentView(R.layout.youractivityen); // english
setTitle(R.string.youractivity_title_en);
}
Intent i = getIntent();
//...`
Upvotes: -1
Reputation: 4104
You can extend Application class (you have to declare it in the manifest as well) and put something like this in it.
Whenever you want to change language you can then call
((App)getApplicationContext()).changeLang(lang);
from within your activity. R.string.locale_lang is just a key which is stored in strings.xml for shared preferences
public class App extends Application {
private Locale locale = null;
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (locale != null) {
Locale.setDefault(locale);
Configuration config = new Configuration(newConfig);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
}
@Override
public void onCreate() {
super.onCreate();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
String lang = settings.getString(getString(R.string.locale_lang), "");
changeLang(lang);
}
public void changeLang(String lang) {
Configuration config = getBaseContext().getResources().getConfiguration();
if (!"".equals(lang) && !config.locale.getLanguage().equals(lang)) {
Editor ed = PreferenceManager.getDefaultSharedPreferences(this).edit();
ed.putString(getString(R.string.locale_lang), lang);
ed.commit();
locale = new Locale(lang);
Locale.setDefault(locale);
Configuration conf = new Configuration(config);
conf.locale = locale;
getBaseContext().getResources().updateConfiguration(conf, getBaseContext().getResources().getDisplayMetrics());
}
}
public String getLang(){
return PreferenceManager.getDefaultSharedPreferences(this).getString(this.getString(R.string.locale_lang), "");
}
}
Upvotes: 19