I'm working on a app in Xamarin.Android and it has to support English and Bulgarian. Most of the text is stored in the Strings.xml in the values folder.
The English text is in the default values folder and the Bulgarian text is in values-bg.
The filename for both is String.xml, and the name of each string is the same as it's translated version.
Now how can I make it so that when i click one button it reads the strings from values-bg and when i click another it reads from the default again? Also I would like that to be so for every activity in the app.
I've been testing how to change locale programmatically, and I finally found a solution that worked for me.
As you said, you need a values folder, containing strings.xml with default values, which would be english, then a values-bg folder, with the same file but with Bulgarian translated values. It is important that strings have the same name, so you did it right.
Then, in your click event, you can add this :
var locale = new Java.Util.Locale ("bg");
Android.Content.Res.Configuration conf = Resources.Configuration;
conf.Locale = locale;
DisplayMetrics dm = Resources.DisplayMetrics;
Resources.UpdateConfiguration (conf, dm);
Recreate ();
First, that code will declare a Locale variable for "bg" locale. Then, it gets the actual configuration of the device, and apply the new Locale to it. Using UpdateConfiguration, it save the changes. The Recreate is optional, it just, as its name explains it all, recreates the current activity, which will be loaded using the new configuration, with a locale "bg" instead of whatever default locale was applied. It will now fetch strings in the values-bg folder.
NOTE : I've read in the comments of the accepted answer here that on some devices, the configuration will reset to default after some time in the app. I'm not sure why this happens, but you might want to check if the locale has been changed somehow when loading a new activity, to prevent that rollback.
Related
I have created a folder values-fr for French localization and placed String.xml with french strings in it. When I change the language in my testing device to french it's not changing. PS: Xamarin Android.
Just to post the answer from the comments.
Try this to get the Locale language (just to check), put it in to OnCreate() method:
Android.Content.Res.Configuration conf = res.Configuration;
var languageCodeValue = conf.Locale;
if the language it's ok, then check the folder name, you can see more information here https://learn.microsoft.com/es-es/xamarin/android/app-fundamentals/localization
Then check the name of the file, Xaml can't recognize the UpperCase, so you need to define all in minus, check if you have named the file strings.xml
I have the folder values with the strings.xml in English and values-es folder with another string.xml in spanish. I have a fragment that gets opened from the action bar to set the settings and store them in SharedPreferences, that works fine in English. I have a lot of if's in the app to check what is set on Share preferences but with the words in English and now in the strings.xml in spanish I want to do something like this to avoid changing all the ifs in the app. I tried this but it doesn't work:
<string-array name="music">
<item value="Yes">Si</item>
<item value="No">No</item>
</string-array>
Is there any way to do something similar? Basically I want the user to select "Si" on the preferences spinner but when I get the value from the spinner I want it to retrieve "Yes"
You should be using constants for the value you need to save in shared preferences that way it will be language independent.
For example if you have 2 radio buttons for music naming on and off you should create 2 constants
public static final int ON = 1;
public static final int OFF = 0;
Now on click of radio button you Should be checking id of radio button and saving appropriate constant in shared preferences:
case: R.id.radio_on
//save ON in shared preferences
break;
case: R.id.radio_off
//save OFF in shared preferences
break;
Then you can check for the constants independent of any language.
Hi please pass the value si which you want to pass to string and take the value yes from your spinner just you can try this example
http://www.androidhive.info/2014/07/android-building-multi-language-supported-app/
Basically I want the user to select "Si" on the preferences spinner
but when I get the value from the spinner I want it to retrieve "Yes"
If you are displaying the values in Splanish and for particular part of code you want to retrieve the value in English below might be the way you are looking for.
Resources res = getResources();
Configuration conf = res.getConfiguration();
Locale savedLocale = conf.locale; // Save your current locale first (Splanish in your case)
conf.locale = new Locale("es"); // Change the desired locale( English in your case)
res.updateConfiguration(conf, null);
// retrieve resources from desired locale
String str = res.getString(id);
// restore original locale
conf.locale = savedLocale;
res.updateConfiguration(conf, null);
I hope it will help.
I have a TextView that displays a message to the user depending on the situation. I get the string to change depending on the situation and that's working great.
My problem is, how do I manage that for different languages?
I've looked around and most suggestions are to use a separate string.xml depending on the locale. But since this is only one string resource that changes its content programmatically it did not really work.
Is there a way to have something like
if(language is blabla)
change the text to "this"
or something of the sort.
You can programatically check the user's language by using class:
http://developer.android.com/reference/java/util/Locale.html
i.e.
Locale.getDefault().toString()
Next you should use path to the appropriate string.xml
You only change bold part:
values-en-rMU
I managed this by using SQLite database. I had 5 different tables for 5 languages. In my listAdapter I imported tables name from query:
SELECT * FROM dbname.sqlite_master WHERE type='table'
Next, in one singleton class called OutputStrings I import all used strings for UI.
From each Activity Views are reading strings from OutputStrings.
Best Regards,
You can easily change your local to your desired local:
Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration mConfig = new Configuration();
mConfig.locale = locale;
getBaseContext().getResources().updateConfiguration(mConfig,
getBaseContext().getResources().getDisplayMetrics());
I'm porting my iPhone app to android and I'm having a problem with the string files now.
The app is a translation tool and users can switch the languages, so all the localized strings are in both languages and they are independent from what locale the OS is running.
For iOS version I have different files like de.strings, en.strings and fr.strings and so on. For every target with specified language pair I read the strings from the string tables, e.g. for de-fr I will include de.strings and fr.strings in project and set the name of the string tables in the info-list file and read strings from them. In the end I have one project containing different targets (with different info-list files) and all are well configured.
I'm intending to do the same on android platform, but
Is only one strings.xml allowed per project?
How do I set different build target? e.g. my de-fr and de-en translation app are actually two apps where the only difference is the language pairs. How can I set something so that I can use one project to generate the two apps? In XCode it's simple but I can't find a solution with eclipse.
How do I specify per target which strings.xml it should read?
Thank you for your answers but Please Note that I need OS locale independent language settings, i.e. if the user changes OS locale from en to de, my app still shows localized strings in English. What I'm asking is actually how I can set something like prebuild and load different string files for different targets.
Automatic locale selection, according to user settings
The strings.xml contains the original text, assuming for the English language.
To create translations into different languages you can create folders, for example:
values-gr, values.it, for the Greek end Italian.
Just copy strings.xml into those folders and translate it.
On application launch, OS automatically picks a language according to the user's preferences.
Manually locale selection, overriding user settings
To force Greek for example you can use:
Locale locale = new Locale("gr");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
You should, of course, provide a Greek translation for this to work.
Read more
You can check the documentation here:
Support Different Languages - Android
you have to put your localized strings in different folders like values-es, values-de, values-fr, etc.
The file must contain the same keys, for example in values folder:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello</string>
</resources>
in values-es folder:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hola</string>
</resources>
and so on.
You have to create one values folder for each language adding the language ISO code of the language you want to have a translation using this format: values-es, values-de, ... In each folder you have to add a strings.xml with strings of its language.
The values folder (withoud country code) will be the default language.
For choose the string language you want to use:
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
public class Main extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String languageToLoad = "fa"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
}
}
ad 1. No you can have as many as you want. See ad 3 for more information.
ad 2. ????
ad 3. To make language selection in our app you should update context. Then proper xml will be selected automatically. Read about this to see how to do it.
i am trying to post my question understable.
I have 2 strings.xml one is for english and another is for Indian Local Language, let it be Tamil.
I have kept the meanings of all the attributes of strings.xml(english) in my tamil strings.xml
Initially my application will load english strings.xml (as normal)
I have button somewhere which should be used to change the language (tamil in this case)
Upon clicking that - my whole app should be reading my tamil strings.xml ..
I know below code only works for default LOCALE
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = Locale.GERMANY;
res.updateConfiguration(conf, dm);
Can this be tweaked to read the my customized strings.xml on the fly?
Any ideas are greatly appreciated.
That is not possible. It's only possible to change the language of your phone and than you will change the language for your app.
why don't you make a settings activity and in there you put an option to change the language that will transfer you user to a locale and text in the settings page on phone?
Tell me if you need a code or something like that.
Do you mean you want to change your language on demand from English to Tamil within your app?
I call this method in my activity onCreate:
public void setupLocale(Activity c, String NewLocale) {
Resources res = c.getBaseContext().getResources();
Configuration newConfig = new Configuration(res.getConfiguration());
newConfig.locale = new Locale(NewLocale);
res.updateConfiguration(newConfig, null);
}
Where c is my activity and NewLocale is the locale string I want to use. e.g "fr" for french, "da" for Danish. Don't know what Tamil is but you probably do.