Reputation: 564
All texts in my app are in res\values\strings.xml.
I should add a second language.
The app should detect the language of Android and then select the appropriate language.
Is it possible to add a language avoiding changing references to strings.xml, such as below:
sensor.client.R.string.operationResult_communicationError
or
<TextView
android:text="@string/common_please_wait"
Any advice please?
Upvotes: 1
Views: 4079
Reputation: 1012
There is a default "values" folder in the res which contains string.xml, right. Now, if you want your app to support other language then create some other "values" folders.
Example:
If you want your app to support "Rusian language", then create folder with the name "values-ru" which will also contain string.xml. And make sure whatever the string name you are using in values folder's string.xml the same name you have to use in values-ru folder's string.xml file.
e.g.
In values folder's : <string name="submit">Submit</string>
In values-ru folder's : <string name="submit">Представить</string>
And see this class now
public class LanguageActivity extends Activity implements OnClickListener
{
private static String TAG = LanguageActivity.class.getSimpleName();
ListView lvLanguage;
ImageButton btnDone;
String langCode = "";
ArrayList<Language> listLanguages = new ArrayList<Language>();
// ListAdapter lsAdapter;
SharedPreferences preferences;
Editor editor;
Intent intent = null;
LanguageAdapter languageAdapter;
String fromWhere;
private String selectedLanguage = "";
private String selectedLanguageCode = "";
boolean isFirstTime = true;
/**
* Locale object to know language set on device.
*/
private Locale localeDevice;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_language);
initView();
initParameters();
}
private void initParameters()
{
preferences = PreferenceManager.getDefaultSharedPreferences(this);
editor = preferences.edit();
Log.i(TAG, "isFirstTime: " + isFirstTime);
fromWhere = getIntent().getStringExtra(Constants.FROM_WHERE);
selectedLanguage = preferences.getString(Constants.LANGUAGE_NAME, "English");
selectedLanguageCode = preferences.getString(Constants.LANGUAGE_CODE, "en");
isFirstTime = preferences.getBoolean(Constants.IS_FIRST_TIME, true);
prepareLanguageList();
}
private void initView()
{
lvLanguage = (ListView) findViewById(R.id.activity_language_lv);
btnDone = (ImageButton) findViewById(R.id.activity_language_btn_done);
btnDone.setVisibility(View.VISIBLE);
btnDone.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.activity_language_btn_done:
Util.setAppLanguage(selectedLanguage, this);
editor.putString(Constants.LANGUAGE_NAME, selectedLanguage);
editor.putString(Constants.LANGUAGE_CODE, selectedLanguageCode);
editor.putBoolean(Constants.IS_FIRST_TIME, false);
editor.commit();
LanguageActivity.this.finish();
Intent intent = new Intent(LanguageActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (fromWhere != null && fromWhere.equals("SettingsActivity"))
{
LanguageActivity.this.finish();
intent = new Intent(LanguageActivity.this, SettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
startActivity(intent);
break;
default:
break;
}
}
@Override
protected void onPause() {
super.onPause();
finish();
}
class Language
{
String name = "";
String languageCode = "";
boolean isSelected = false;
/**
* @return the name
*/
public String getName()
{
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name)
{
this.name = name;
}
/**
* @return the languageCode
*/
public String getLanguageCode()
{
return languageCode;
}
/**
* @param languageCode
* the languageCode to set
*/
public void setLanguageCode(String languageCode)
{
this.languageCode = languageCode;
}
/**
* @return the isSelected
*/
public boolean isSelected()
{
return isSelected;
}
/**
* @param isSelected
* the isSelected to set
*/
public void setSelected(boolean isSelected)
{
this.isSelected = isSelected;
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
/**
* LanguageAdapter : ArrayAdapter class which prepares view for list of
* languages.
*
* @author MindBowser
*/
class LanguageAdapter extends ArrayAdapter<Language>
{
LanguageAdapter(Context context, ArrayList<Language> list)
{
super(context, R.layout.row_language, R.id.row_language_tv, list);
}
public View getView(int position, View convertView, ViewGroup parent)
{
View row = super.getView(position, convertView, parent);
LanguageViewHolder holder = (LanguageViewHolder) row.getTag();
if (holder == null)
{
holder = new LanguageViewHolder(row);
row.setTag(holder);
}
final Language language = getLanguage(position);
holder.tvLanguage.setText(language.getName());
holder.btnSelect.setBackgroundResource(language.isSelected() ? R.drawable.ic_checked_radio : R.drawable.ic_unchecked_radio);
holder.btnSelect.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
for (Language languageS : listLanguages)
{
if (language.getName().equals(languageS.getName()))
{
languageS.setSelected(true);
Log.i(TAG, "Selected language : " + language.getName());
selectedLanguage = language.getName();
selectedLanguageCode = language.getLanguageCode();
} else
languageS.setSelected(false);
}
notifyDataSetChanged();
}
});
return row;
}
}
class LanguageViewHolder
{
public TextView tvLanguage;
public Button btnSelect;
public LanguageViewHolder(View base)
{
this.tvLanguage = (TextView) base.findViewById(R.id.row_language_tv);
this.btnSelect = (Button) base.findViewById(R.id.row_language_btn);
}
}
/**
* @param position
* @return Language object from specified position
*/
private Language getLanguage(int position)
{
return (Language) languageAdapter.getItem(position);
}
/**
* Prepare list of <b>Language</b> from string array.
*/
void prepareLanguageList()
{
listLanguages = new ArrayList<Language>();
localeDevice = getResources().getConfiguration().locale;
Log.i(TAG, "displayLanguage : " + Locale.getDefault().getDisplayLanguage());
Log.i(TAG, "Language : " + Locale.getDefault().getLanguage());
Log.i(TAG, "localeDevice : " + localeDevice);
String[] arrayLanguages = getResources().getStringArray(R.array.languages);
int noOfLanguages = arrayLanguages.length;
for (int i = 0; i < noOfLanguages; i++)
{
String strLang = arrayLanguages[i];
String[] splitLang = strLang.split(":");
Language language = new Language();
language.setName(splitLang[0]);
language.setLanguageCode(splitLang[1]);
Log.i(TAG, "selectedLanguageCode : " + selectedLanguageCode);
Log.i(TAG, "selectedLanguage : " + selectedLanguage);
Log.i(TAG, "strLang : " + strLang);
// On first time arrival of user we will set the device's default
// language.
// Otherwise set the language selected by user.
if ((isFirstTime && localeDevice.toString().contains(splitLang[1])) || selectedLanguageCode.equals(splitLang[1]))
{
language.setSelected(true);
selectedLanguage = language.getName();
selectedLanguageCode = language.getLanguageCode();
}
// else if (selectedLanguageCode.equals(splitLang[1]))
// {
// language.setSelected(true);
// selectedLanguage = language.getName();
// selectedLanguageCode = language.getLanguageCode();
// }
listLanguages.add(language);
}
for (Language language : listLanguages)
{
Log.i(TAG, "" + language.getName() + " : " + language.isSelected());
}
Log.i(TAG, "selectedLanguageCode : " + selectedLanguageCode);
Log.i(TAG, "selectedLanguage : " + selectedLanguage);
Util.setAppLanguage(selectedLanguage, this);
languageAdapter = new LanguageAdapter(this, listLanguages);
lvLanguage.setAdapter(languageAdapter);
languageAdapter.notifyDataSetChanged();
}
}
public static void setAppLanguage(String language, Context context) {
Resources resources = context.getResources();
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
Configuration configuration = resources.getConfiguration();
Log.i(TAG, "language: " + language);
if (language.equals("Chinese")) {
configuration.locale = Locale.CHINESE;
} else if (language.equals("Japanese")) {
configuration.locale = Locale.JAPANESE;
} else if (language.equals("Malay")) {
configuration.locale = new Locale("ms");
} else if (language.equals("Vietnam")) {
configuration.locale = new Locale("vi");
} else if (language.equals("Danish")) {
configuration.locale = new Locale("da");
} else if (language.equals("French")) {
configuration.locale = new Locale("fr");
} else if (language.equals("Hungarian")) {
configuration.locale = new Locale("hu");
} else if (language.equals("Swedish")) {
configuration.locale = new Locale("sv");
} else if (language.equals("Korean")) {
configuration.locale = new Locale("ko");
} else if (language.equals("Russian")) {
configuration.locale = new Locale("ru");
} else if (language.equals("Spanish")) {
configuration.locale = new Locale("es");
} else {
configuration.locale = Locale.ENGLISH;
}
resources.updateConfiguration(configuration, displayMetrics);
}
Upvotes: 2
Reputation: 4286
You need values-xx folders for each language and then strings.xml file in each of these folders. In eclipse, all these values-xx folders are shown separately in /res folder. In android studio, you click on values and it will show you all the values-xx folders. step by step tutorial: https://www.youtube.com/watch?v=og3BqpZMw7Q
Upvotes: 1
Reputation:
Take a look at this link. In short, you should provide multiple strings.xml
for each language you will support in your app.
Upvotes: 2