The understanding that the text used in the program is a separate resource, the same as images and sound, comes to immediately. But it is worth several times to change the name of the program in a couple of dozen files, or to fix the same type of syntax error in five, six different places and the need to keep the lines separate from the code becomes obvious.
In Android, working with string resources is very convenient and does not cause at first any difficulties. In the official documentation, it is described in the article
String Resources . In the
project \ res \ values \ strings.xml file, set the string and its name and then load the string into the Activity by that name.
strings.xml<?xml version="1.0" encoding="utf-8"?> <resources> <string name="appName">Project Name</string> </resources>
ProjectActivity.java public class LoadingActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { String applicationName = getString(R.string.appName); }
The same line can be used in the xml file layout form (layout resource). How this is implemented can be viewed by creating a new project and opening the
main.xml file.
main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/appName" /> </LinearLayout>
Resource description
Now a few more interesting things, which are also described in the documentation, but which are not so widely used.
Files with strings (as well as with other resources) can be several. The main thing is that they are in the
project \ res \ values \ folder, have the
xml extension, the name consisted of lowercase English letters, numbers and did not contain spaces. The internal structure should follow the structure of the strings.xml file. What can it be used for? I keep in one file all the lines that need to be translated, in the second line, which do not require translation, in the third file I keep the constants that I use to compose requests to the web server.
The XML file has small restrictions on the format of the stored data. In the open form, it cannot use the characters '&', '<'. These characters can be set using a special sequence.
<- & lt;
& - & amp;
Additional restrictions are imposed on the work with single and double apostrophes: use unpaired apostrophes simply cannot be. There are several methods to solve this problem, the simplest of which is to add a backslash before the apostrophe sign:
'- \' or & apos;
"- \" or & quot;
If the text contains html tags and it contains an unbreakable space & nbsp; then it must be replaced with & # 160 ;.
Loading rows
If you need to set the text from the resources of one of the interface elements, then there is no need to download it in advance. The second and third lines in the above example work exactly the same.
TextView sectionHeader = (TextView)findViewById(R.id.sectionHeader); sectionHeader.setText(getString(R.string.sectionPhone)); sectionHeader.setText(R.string.sectionPhone);
The
getString method is useful when you need to add additional data to a string from resources before further use. In this case, the formatted string is placed in the resources and the additional parameters for it are specified directly in
getString , without an additional call to the
String.format method. Examples divided by a trait produce the same results:
int sectionId = 10; String header = getString(R.id.headerSection); sectionHeader.setText(String.format(header, sectionId));
The format of the string is as follows:% X $ F.
X $ is the number of the parameter being substituted. In the main text, they usually go in order of $ 1, $ 2, but in localized resources they can change places. It is also allowed to use one parameter per line several times.
F is a common format identifier, such as 's', 'd'. Their complete list, including date formatting, is described in the
Formatter class documentation
.If the line uses only one parameter, then X $ can be omitted. If the parameters are inconvenient to read, and there are no problems with localization, then you can return to the standard string formatting scheme - for this, you need to add the
formatted attribute with the value
false to the element description. The following two lines format the text in the same way:
<string name="score_correct">%1$d - %2$d</string> <string name="score_simple" formatted="false">%d - %d</string>
You can load a string by its name just like any other resource. To do this, you first need to use the
getIdentifier method by the name of the string to find its
id , and with this number you should work with the usual way. The following example loads a string named “score_correct”.
int strId = getResources().getIdentifier("score_correct", "string", getPackageName()); String strValue = getString(strId);
Android allows storing arrays in resources. This is done using the
string-array tag, which contains
item elements with specific strings inside. Here is an abbreviated example from the Android documentation that illustrates the task of the array.
strings.xml <string-array name="planets_array"> <item>Earth</item> <item>Mars</item> </string-array>
In addition to the obvious application - convenient data loading,
string-array is often used to initialize UI elements with a drop-down list of values:
Spiner and
ListPreference . In this case, you usually need to use one of the rows of the array as the default value. We cannot refer to resources on a specific element of the array, but we can get out of the situation by using
aliases for the resources .
The array elements are initialized as normal strings, and the
item elements contain only a link to them. Such initialization is in fact extremely convenient and I use it even in those cases when reference to a specific string is not planned - this ensures that when lokazatsii all arrays will be the same size, even if some of the strings in them will not be translated. The description of the array itself is conveniently placed in a separate resource file.
An example rewritten using aliases is as follows:
')
strings.xml <string name="earth">Earth</string> <string name="mars">Mars</string> <string-array name="planets_array"> <item>@string/earth</item> <item>@string/mars</item> </string-array>
A useful note: prior to the Android 2.3 version, there was an error in the implementation of the string-array loading, which allowed only a maximum of 512 items to be loaded.
System strings
Android gives you access to several lines stored in system resources. Some of them are quite specialized: the title of the video playback error message. But strings such as “Ok” or “Cancel” are conveniently used in almost every project. Using system strings is almost as easy as using your own resources — you need to specify the name
android before the resource identifier
string with a colon. The following example describes a button that says “Cancel” using a string from system resources.
main.xml <Button android:text="@android:string/cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" />
String localization
The basic mechanism of localization of resources in Android makes it easy to solve almost all problems with the localization of strings. A full description in the Android documentation can be found
here . In the resources you need to create a new folder named
values-xx and place there files with string resources from the base
values folder.
xx is a two-character language identifier (a list of supported values is given at the end of the text). After that, the necessary lines need to be translated, the rest are deleted.
For more subtle localization, you can use the mechanism for setting the region. For example, you have a user agreement translated into French in the program, but there are differences in it between the version for France and the version for Canada. To realize these differences, you need to add the name of the region in the format
rYY to the
values-fr folder , where
YY is the two-character name of the region. In this example, the
values-fr-rFR and
values-fr-rCA folders will be obtained. They should put the resource file with the required version of the user agreement, and leave all the other lines in French in the
values-fr folder.
Regions and language can be specified without any connection with each other. So in the
values-ru-rJP folder, Russian texts for the people of Japan will be stored.
Since there are definitely not many regions, in most cases it is more convenient to specify the exact country identifier instead using the
mcc property (mobile country code). The list of codes is available on
Wikipedia and the only drawback of this method is that some countries have several codes (the US uses 7 numbers, Japan 2 numbers). Redesigning the example to use
mcc we get the
values-mcc208-fr folders for France and the
values-mcc302-fr folders for Canada.
Difficulties with localization begin at the moment when you need to localize the application to a language that is not supported by the system. Getting into this situation is easy, because most languages and regions were added only in version 2.3 of the platform. However, some manufacturers added support for other languages in their devices, but used different codes. As a result, the Norwegian language in Android 2.1 and 2.2 is recognized on many devices by the
no code, not recognized on some devices, and since Android 2.3 it is recognized by the
nb code. The same situation, but on a smaller scale, with Hebrew, which can occur under the code
he and Indonesian language - the code
id .
In this case, in order not to store two sets of identical strings in different files, you can use aliases for resources that have already been mentioned before.
In this case, the actual translation of the strings is stored in the
values folder, with the working names being used for their names. The
values-no and
values-nb folders contain links to strings and the actual names of resources are already used here.
values / strings.xml <resources> <string name="hello">Hello World</string> <string name="hello_translate">Hallo Verden</string> </resources>
values-no / strings.xml <resources> <string name="hello">@string/hello_translate</string> </resources>
values-nb / strings.xml <resources> <string name="hello">@string/hello_translate</string> </resources>
You can create resources with any codes for the language and for the region. If the operating system does not find the desired region, it will take values for the current language. If it cannot find the language, it will retrieve the default values from the
values folder.
You can download resource strings for a language and region other than those installed on the device. To do this, you need to create a new resource and set it the necessary locale. The following example loads a string for French.
Resources baseResources = getResources(); Configuration config = new Configuration(baseResources.getConfiguration()); config.locale = Locale.FRANCE; Resources localResources = new Resources(baseResources.getAssets(), baseResources.getDisplayMetrics(), config); String strFranceValue = localResources.getString(R.string.score_correct);
You can also programmatically set an arbitrary language for the entire application, but this task is beyond the scope of this topic.
application
Supported languages before Android 2.3
English (en), Dutch (nl), Spanish (es), Italian (it), Chinese (zh), Korean (ko), German (de), German (de), Polish (pl), Russian (ru), French (fr), Czech (cs), Japanese (ja)
Supported languages starting with Android 2.3
Arabic (ar), Bulgarian (bg), Hungarian (hu), Vietnamese (vi), Greek (el), Danish (da), Hebrew (iw), Indonesian (in), Catalan (ca), Latvian (lv), Lithuanian (lt), Norwegian-Bukmol (nb), Portuguese (pt), Romanian (ro), Serbian (sr), Slovak (sk), Slovenian (sl), Tagalog (tl), Thai (th), Turkish (tr ), Ukrainian (uk), Finnish (fi), Hindi (hi), Croatian (hr), Swedish (sv)
Supported regions to Android 2.3
Australia (AU), Austria (AT), Belgium (BE), Britain (GB), Germany (DE), Spain (ES), Italy (IT), Canada (CA), China (CN), Korea (KR), Liechtenstein (LI), Netherlands (NL), New Zealand (NZ), Poland (PL), Russia (RU), Singapore (SG), USA (US), Taiwan (TW), France (FR), Czech Republic (CZ ), Switzerland (CH), Japan (JP)
Supported regions starting with Android 2.3
Bulgaria (BG), Brazil (BR), Hungary (HU), Vietnam (VN), Greece (GR), Denmark (DK), Egypt (EG), Zimbabwe (ZA), Israel (IL), India (IN), Indonesia (ID), Ireland (IE), Latvia (LV), Lithuania (LT), Norway (NO), Portugal (PT), Romania (RO), Serbia (RS), Slovakia (SK), Slovenia (SI), Thailand (TH), Turkey (TR), Ukraine (UA), Philippines (PH), Finland (FI) Bulgaria (BG), Brazil (BR), Hungary (HU), Vietnam (VN), Greece (GR), Denmark (DK), Egypt (EG), Zimbabwe (ZA), Israel (IL), India (IN), Indonesia (ID), Ireland (IE), Latvia (LV), Lithuania (LT), Norway (NO), Portugal (PT), Romania (RO), Serbia (RS), Slovakia (SK), Slovenia (SI), Thailand (TH), Turkey (TR), U Raina (UA), Philippines (PH), Finland (FI), Croatia (HR), Sweden (SE)
Update: Added a section on string arrays, string localization, system strings. Removed example using resources to transfer data between different Activities.