I'm implementing an app in Hebrew, and I like it to be user-friendly in such way that at the first time the user logs on, there will be a question "Are you a male or a female?". After answering this question, I want most of the strings to be gender-dependent
(E.g. in Hebrew the question "Would you like some coffee?" will be
תרצה לשתות קפה?
for a male, and -
תרצי לשתות קפה?
for a female)
Meanwhile my app supports English and Unisex-Hebrew Locales, so I'm using String resources (like R.string.somevalue) and I know how to handle values-he and values-en.
Let's say I can ask for is_male() and is_locale_hebrew() at anytime, I saw this answer but it won't help my case since there are a hell lot of strings in my working-already app and I want the solution to add only xml files (hopefully) with the less needed change in my "Activity"s code.
I thought maybe overloading the parser that looks for the xml files will do the magic, but I have no clue where to start from.
My question divides into two parts:
A. How can I implement gender-dependnt String-resources?
B. (Opt) Some of the string-resources are good as unisex right now, is there any option to avoid copying those resources to the 2 new gender-dependent files and just add a default behavior of "if you don't find a string resource at values-he-male search for it in values-he"?
Thanks in advance!
Re'em
Same question for me. I plan to have (in addition to the default string.xml in English) iw (for male) and iw_fe (for female).
When the user selects his/her gender, I will change the locale (Set Locale programmatically )
As for using default values in Hebrew, I am still clueless. For now I will simply copy the Hebrew XML and change the required entries, leaving all the rest intact.
HTH
Noam
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Wanted to ask about the strings.xml in an Android project. I often see that the normal usage is to put all text for the entire App in the strings.xml. And I have also seen that strings.xml holds system strings and the rest is stored in xml files that have the name of the class. like this:
ActivityMain.java (having many text strings for user to read)
activity_main.xml (holding all text strings for ActivityMain.java)
I look trough android-best-practices but finds no mentioning of this.
Maybe this does not matter but what is your view on this, pros and cons?
To manage the strings for your project, the best approachment (From my not quite long experience) is to split the strings related to it's usage.
For example,
if you have 2 Activity: MainActivity.java with activity_main.xml (let's call them MainActivity) and SecondActivity.java with activity_second.xml, you need to split the string based on the activity name. So you need to make:
strings_main.xml
strings_second.xml
in the strings_main.xml, you need to use activityname_text pattern. For example, if in the MainActivity you have a Title TextView then you need to add:
<string name="main_title">My Title</string>
For untranslatable string in MainActivity, you can add something like this:
<string name="main_app_name" translatable="false">MyAppName</string>
<string name="main_developer_name" translatable="false">My Developer Name</string>
This approach is suitable if you have a large project where each distinct Activity (or package) is maintained by another developer. And this approach will make sure you not accidentally alter the text for other Activity than your current edited Activity.
For multiple language, we just need to make a folder based on the language. For example, for Indonesia language we just need to add values-in folder. Then we can copy the strings xml from values folder. More for Supporting Different Languages.
When adding a different language for an app (For example, Indonesia language), Android Studio will complaining about missing translation if there is a string in values but not in values-in. For example, if in values we have:
<string name="main_title">My Title</string>
But not exist in values-in then Android Studio will complaining about the non exist translation when Build-> Release the app. We can fix the error by adding translatable=false:
<string name="main_title" translatable="false">My Title</string>
We also can change the translation because there is Translation Editor in Android Studio.
For project naming convention, you can look at Ribot android-guidelines.
It all depends on your preferences. And there is really many ways of storing Strings. As many as coding styles.
One way: store all in strings.xml . This can be OK for small project,
but when quantity of strings will be over 50, all'll look messed up.
Second way: store by usage purpose. Something like login_error_strings.xml and so on. This idea is described here
Third way: store in static fields. Create some Const.class and put there all what do you want. I don't really know what is drawback of it, but there is diffidently something wrong.
Just to clarify: I think that "second way" is best way of doing this.
Basically what I am trying to do is,
I start with MainActivity(activity_main) go to SettingActivity(activity_setting) & change my locale from given options(like french, english, dutch etc.)
So what I have done till now is...
OnClick of language name it re-create SettingActivity(activity-setting) & change it's string values according to language selected.
What I really want is Without re-creating Activity, All string values should be applied according to that selected language.
All suggestions & Answers are greatly appreciated.
Thank you in Advance.
Simply change the language property first.
Then call a new function that sets all strings displayed in the UI to the right language.
Pseudocode:
TextView myTextView = (TextView) findViewbyId(R.id.tv1);
myTextView.setText(yourCustomGetLocaleFunction("some id of the string you want to display", "some language name"));
But that's a bad approach. You should let Android handle the language of your app. Just localize the strings.xml file (you can load strings from the file from code).
Edit:
To change the language of your app for the moment, you can use the Code from this solution:
How to change android app language without changing phone language?
My country (Spain) has several languages (es-ES, ca-ES, gl-ES, eu-ES). We won't add all the languages for now so we would like to use main language in Spain, i.e. Spanish (es). We would like to display the /values-es/strings.xml when the user has selected one of the other languages in the country. How can we do that?
Oh, and we would like to use English as the default language (/values/strings.xml).
It would be great to have something like /values-ES/strings.xml, but I suppose that can't be done because the first code should be the language code.
Now we are copying the /values-es/strings.xml file to the other folders (values-ca, values-gl and values-eu) but we'd like to avoid that.
I think that you should have only 2 folders with 1 strings.xml for each other:
res/values/strings.xml this resource will contains your text in English ;
res/values-es/strings.xml this resource will contains your text in Spanish .
When your app is installed on a device which is configured with the Italian language, it will use the file resource on case 1.
When your app is installed on a device which is configured with a Spanish language (and there are a lot of Spanish language out there, think about South America countries), it will use the file resource on case 2.
You can do it easily with Android Studio:
right-click on res folder
go to New > Android resource directory
a window will show you some options; pick Locale and then click on the button with those symbols "> >"
then on the Language list, pick es: Spanish and then click OK, as showed in the image below (note that by default the Specific Region Only has Any Region selected!)
By experience: I never faced up a Breton, Corsican or Provençal users claiming for a full translation of the application in their language (by default the app has English as default and French).
I would say you want to do something like this.
if (Locale.getDefault().getISO3Country().equals("ESP"))
{
Locale[] locales = Locale.getAvailableLocales();
for (Locale loc : locales)
if (loc.getISO3Language().equals("SPA"))
{
Locale.setDefault(loc);
break;
}
}
Note: I'm not sure if I got the ISO3 language and country codes right. And you'll also have to do something for the (rare?) situation that the es-ES locale is not available.
If you are trying to override Catalan with Spanish, you should probably have that in the values-ca/strings.xml file.
The way to do what you are asking is to provide the resources in the appropriate mobile country code resource folder, which takes precedence over language-region resources.
Assume that you have the following situation:
The application code calls for R.string.text_a
Two relevant resource files are available:
res/values-mcc404/strings.xml, which includes text_a in the application's default language, in this case English.
res/values-hi/strings.xml, which includes text_a in Hindi.
The application is running on a device that has the following configuration:
The SIM card is connected to a mobile network in India (MCC 404).
The language is set to Hindi (hi).
Android will load text_a from res/values-mcc404/strings.xml (in English), even if the device is configured for Hindi. That is because in the resource-selection process, Android will prefer an MCC match over a language match.
The MCC for Spain is 214.
(See Localization)
I found another tricky solution: hard links. Although it doesn't remove whole problem completely, at least it protects you from routine task of copying file across multiple directories or making equal changes in all existed files with risk of miss something.
But I must admit that there is some caveats:
1) Some IDE does not support working with hard links by-default. Intellij IDEA and Android Studio will break your hard links if you don't disable "safe write" option in settings.
2) Most version control systems also doesn't support hard links by default. Let's take git for example. It will break existing hard links after reverting or merging changes.
Currently, I'm using batch file for restoring hard links after they get broken by git.
In a general term, there should be only one strings.xml file under values folder containing the relevant data.
If we explicitly specify different values folder like values-ca,values-es, whenever there are setting changes in the android device, it will look to the particular folder and take the appropriate strings value.
If the requirement is keep uniform text means better have only values->strings.xml file alone with the required data.
But with this approach multilingual apk is not possible i.e. for other country different language is expected, there will be variations again. So wherever we need uniform language, lets go with single folder alone and wherever multilingual is preferred, we can have multiple values-es,values-ca folder like that.
Hope that helps
How about trying to set it in java, instead of using strings.xml.
As doing it programatically gives you more flexibility at run-time.
Configuration config = new Configuration(getResources().getConfiguration());
Locale locale = Locale.getDefault();
String country = locale.getCountry();
String language = locale.getLanguage();
if (country.equalsIgnoreCase("ES") && (language.equalsIgnoreCase("ca") || language.equalsIgnoreCase("gl") || language.equalsIgnoreCase("eu"))) {
locale = new Locale("es");
}
config.setLocale(locale);
And then you can simply have one /values-es/strings.xml for all the ES country languages.
I wrote a big app with thousands of string in the code.... very bad idea, because now I want to translate each string.... big problem.
Copying all strings to the strings.xml takes a long time.
Eclipse has an option to take all selected strings and put them into messages.properties.
Does this work similiar like strings.xml? When, why all people use strings.xml.
Or should is use eclipse to seperate each string and than I should copy them to string.xml?
All people are using strings.xml because this is the normal way to do it on Android. You don't have to manage the load of the strings, to call any locale function in your script.
You can see the documentation here : http://developer.android.com/guide/topics/resources/index.html
BTW, you can easily transform your eclipse generated file to an strings.xml file after the extraction.
In Eclipse you can use the shortcut keys Alt + Shift A, S to extract an inline string in to the strings.xml file via a popup dialog - might be a bit easier than doing it by hand. And as the others say, yes you should ALWAYS use the strings.xml file so that you only have to look in one place when you want to change a string, instead of having to search through all your code.
Are there any suggestions on which strings you should store in strings.xml and which strings can be stored as String objects? For example, do I have to put a string into strings.xml, if I use it only to complete a certain action and then it can be destroyed? And what is the main reason in storing strings in xml? Thanks in advance for your answers.
Any string that will be displayed to the user should be in strings.xml. This is useful in case you ever want to support other languages for your application. If you do, you just create a new strings.xml file that language with translated values. You can learn more about it here.
One reason is multi-language support.
You should store the strings that you use in Activities - TextView, button's caption and so on.
You should put most constants in strings.xml, your app title, button names, textview contents...mostly things that wont change in your application.
Another reason for storing strings in xml is for localization. You can store different files for each different Locale or language, and Android will grab the correct file for the phone's selected Locale or language.
Here is a link to the String resource Android page, it will go more deeply into how the language support is done.
You don't store all the strings in strings.xml, but only strings constants related to user interface, the strings that you want to translate in different languages.
You can have different folder like :
values
values-fr
values-de
in each a strings.xml file with you UI messages translated in many languages.
Regards,
Stéphane