1page.title=Hello, L10N 2parent.title=Tutorials 3parent.link=../../browser.html?tag=tutorial 4@jd:body 5 6<div id="qv-wrapper"> 7 <div id="qv"> 8 <h2>In this document</h2> 9 <ol> 10 <li><a href="#unlocalized">Create an Unlocalized App</a> 11 <ol> 12 <li><a href="#create">Create the Project and Layout</a></li> 13 <li><a href="#default">Create Default Resources</a></li> 14 </ol> 15 </li> 16 <li><a href="#run">Run the Unlocalized App</a></li> 17 <li><a href="#plan">Plan the Localization</a></li> 18 <li><a href="#localize">Localize the App</a> 19 <ol> 20 <li><a href="#localize_strings">Localize the Strings</a></li> 21 <li><a href="#localize_images">Localize the Images</a></li> 22 </ol> 23 </li> 24 <li><a href="#test_localized">Run and Test the Localized App</a></li> 25 </ol> 26 <h2>See also</h2> 27 <ol> 28<li>{@link android.widget.Button}</li> 29<li>{@link android.widget.TextView}</li> 30<li>{@link android.app.AlertDialog}</li> 31</ol> 32 </div> 33</div> 34 35<p>In this tutorial, we will create a Hello, L10N application that uses the 36Android framework to selectively load resources. Then we will localize the 37application by adding resources to the <code>res/</code> directory. </p> 38 39<p>This tutorial uses the practices described in the <a 40href="{@docRoot}guide/topics/resources/localization.html">Localization</a> 41document. </p> 42 43 44<h2 id="unlocalized">Create an Unlocalized Application</h2> 45 46<p>The first version of the Hello, L10N application will use only the default 47resource directories (<code>res/drawable</code>, <code>res/layout</code>, and 48<code>res/values</code>). These resources are not localized — they are the 49graphics, layout, and strings that we expect the application to use most often. 50When a user runs the application in the default locale, or in a locale that the 51application does not specifically support, the application will load resources 52from these default directories.</p> 53 54<p>The application consists of a simple user interface that displays two 55{@link android.widget.TextView} objects and a {@link android.widget.Button} image with a 56 background image of a national flag. When clicked, the button displays an 57{@link android.app.AlertDialog} object that shows additional text. </p> 58 59<h3 id="create">Create the Project and Layout</h3> 60 61<p>For this application, the default language will be British English and the 62default location the United Kingdom. </p> 63 64<ol> 65 <li>Start a new project and Activity called "HelloL10N." If you are 66using Eclipse, fill out these values in the New Android Project wizard: 67 <ul> 68 <li><em>Project name:</em> HelloL10N</li> 69 <li><em>Application name:</em> Hello, L10N</li> 70 <li><em>Package name:</em> com.example.hellol10n (or your own private 71namespace)</li> 72 <li><em>Create Activity:</em> HelloL10N</li> 73 <li><em>Min SDK Version:</em> 3</li> 74 </ul> 75 <p>The basic project contains a <code>res/</code> directory with 76subdirectories for the three most common types of resources: graphics 77(<code>res/drawable/</code>), layouts (<code>res/layout/</code>) and strings 78(<code>res/values/</code>). Most of the localization work you do later in this 79tutorial will involve adding more subdirectories to the <code>res/</code> 80directory.</p> 81 <img src="{@docRoot}images/hello_l10n/plain_project.png" alt="plain project" width="194" 82height="229"> 83 </li> 84 <li>Open the <code>res/layout/main.xml</code> file and replace it with the 85following code: 86 <pre><?xml version="1.0" encoding="utf-8"?> 87<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 88 android:orientation="vertical" 89 android:layout_width="fill_parent" 90 android:layout_height="fill_parent" 91 > 92<TextView 93 android:layout_width="fill_parent" 94 android:layout_height="wrap_content" 95 android:gravity="center_horizontal" 96 android:text="@string/text_a" 97 /> 98<TextView 99 android:layout_width="fill_parent" 100 android:layout_height="wrap_content" 101 android:gravity="center_horizontal" 102 android:text="@string/text_b" 103 /> 104<Button 105 android:id="@+id/flag_button" 106 android:layout_width="wrap_content" 107 android:layout_height="wrap_content" 108 android:layout_gravity="center" 109 /> 110</LinearLayout> 111 </pre> 112 113 <p>The LinearLayout has two {@link android.widget.TextView} objects that will 114display localized text and one {@link android.widget.Button} that shows a flag. 115</p> 116 </li> 117</ol> 118 119<h3 id="default">Create Default Resources</h3> 120 121<p>The layout refers to resources that need to be defined. </p> 122 123<ol> 124 <li>Create default text strings. To do this, open the <code>res/values/strings.xml</code> file and replace it with the following code:<br> 125 <pre><?xml version="1.0" encoding="utf-8"?> 126<resources> 127 <string name="app_name">Hello, L10N</string> 128 <string name="text_a">Shall I compare thee to a summer"'"s day?</string> 129 <string name="text_b">Thou art more lovely and more temperate.</string> 130 <string name="dialog_title">No Localisation</string> 131 <string name="dialog_text">This dialog box"'"s strings are not localised. For every locale, the text here will come from values/strings.xml.</string> 132</resources></pre> 133 134 <p>This code provides British English text for each string that the application 135will use. When we localize this application, we will provide alternate text in 136German, French, and Japanese for some of the strings.</p> 137 </li> 138 <li>Add a default flag graphic to the <code>res/drawable</code> folder by 139saving <a href="../../../images/hello_l10n/flag.png">flag.png</a> as 140<code>res/drawable/flag.png</code>. When the application is not localized, it 141will show a British flag.<br> 142 143 </li> 144 <li>Open HelloL10N.java (in the <code>src/</code> directory) and add the 145following code inside the <code>onCreate()</code> method (after 146<code>setContentView</code>). 147 148 <pre>// assign flag.png to the button, loading correct flag image for current locale 149Button b; 150(b = (Button)findViewById(R.id.flag_button)).setBackgroundDrawable(this.getResources().getDrawable(R.drawable.flag)); 151 152// build dialog box to display when user clicks the flag 153AlertDialog.Builder builder = new AlertDialog.Builder(this); 154builder.setMessage(R.string.dialog_text) 155 .setCancelable(false) 156 .setTitle(R.string.dialog_title) 157 .setPositiveButton("Done", new DialogInterface.OnClickListener() { 158 public void onClick(DialogInterface dialog, int id) { 159 dialog.dismiss(); 160 } 161 }); 162final AlertDialog alert = builder.create(); 163 164// set click listener on the flag to show the dialog box 165b.setOnClickListener(new View.OnClickListener() { 166 public void onClick(View v) { 167 alert.show(); 168 } 169 });</pre> 170 171 <p class="note"><strong>Tip:</strong> In Eclipse, use 172<strong>Ctrl-Shift-O</strong> (<strong>Cmd-Shift-O</strong>, on Mac) to find and 173add missing import packages to your project, then save the HelloL10N.java 174file.</p> 175 176 <p>The code that you added does the following:</p> 177 178 <ul> 179 <li>It assigns the correct flag icon to the button. 180 For now, no resources are defined other than the default, so this code 181will always assign the contents of <code>res/drawable/flag.png</code> (the 182British flag) as the flag icon, no matter what the locale. Once we add more 183flags for different locales, this code will sometimes assign a different flag. 184</li> 185 <li>It creates an {@link android.app.AlertDialog} object and sets a click listener so that when the 186user clicks the button, the AlertDialog will display. 187 We will not localize the dialog text; 188the AlertDialog will always display the <code>dialog_text</code> that is located 189within <code>res/values/strings.xml</code>. </li> 190 </ul> 191 192 </li> 193</ol> 194 195<p>The project structure now looks like this:</p> 196 197 <img src="{@docRoot}images/hello_l10n/nonlocalized_project.png" alt="nonlocalized" width="394" 198height="320"> 199 200<p class="note"><strong>Tip:</strong> If you will want to run the application on 201a device and not just on an emulator, open <code>AndroidManifest.xml</code> and 202add <code>android:debuggable="true"</code> inside the 203<code><application></code> element. For information about setting up the 204device itself so it can run applications from your system, see <a 205href="{@docRoot}guide/developing/device.html">Developing on a Device</a>.</p> 206 207 208<h2 id="run">Run the Unlocalized Application</h2> 209 210<p>Save the project and run the application to see how it works. No matter what 211locale your device or emulator is set to, the application runs the same way. It 212should look something like this:</p> 213 214<table border="0" cellspacing="0" cellpadding="30"> 215 <tr> 216 <th scope="col">The unlocalized application, running in any locale:</th> 217 <th scope="col">After clicking the flag, in any locale:</th> 218 </tr> 219 <tr> 220 <td valign="top"><img src="{@docRoot}images/hello_l10n/nonlocalized_screenshot1.png" 221alt="nonlocalized" width="321" height="366"></td> 222 <td><img src="{@docRoot}images/hello_l10n/nonlocalized_screenshot2.png" alt="nonlocalized2" 223width="321" height="366"></td> 224 </tr> 225</table> 226<h2 id="plan">Plan the Localization</h2> 227<p>The first step in localizing an application is to plan how the application 228will render differently in different locales. In this application, the default 229locale will be the United Kingdom. We will add some locale-specific information 230for Germany, France, Canada, Japan, and the United States. Table 1 shows the 231plan for how the application will appear in different locales.</p> 232 233<p class="caption">Table 1</p> 234 235<table border="0" cellspacing="0" cellpadding="10"> 236 <tr> 237 <th scope="col" valign="bottom">Region /<br /> 238 Language</th> 239 <th scope="col">United Kingdom</th> 240 <th scope="col">Germany</th> 241 <th scope="col">France</th> 242 <th scope="col">Canada</th> 243 <th scope="col">Japan</th> 244 <th scope="col">United States</th> 245 <th scope="col">Other Location</th> 246 </tr> 247 <tr> 248 <th scope="row"><br> 249 English</th> 250 <td> British English text; British flag <em>(default)</em></td> 251 <td><em>-</em></td> 252 <td><em>-</em></td> 253 <td> British English text; Canadian flag</td> 254 <td>-</td> 255 <td> British English text; U.S. flag</td> 256 <td> British English text; British flag <em>(default)</em></td> 257 </tr> 258 <tr> 259 <th scope="row">German</th> 260 <td>-</td> 261 <td>German text for <code>app_name</code>, <code>text_a</code> and 262<code>text_b</code>; German flag</td> 263 <td>-</td> 264 <td>-</td> 265 <td>-</td> 266 <td>-</td> 267 <td>German text for <code>app_name</code>, <code>text_a</code> and 268<code>text_b</code>; British flag</td> 269 </tr> 270 <tr> 271 <th scope="row">French</th> 272 <td>-</td> 273 <td>-</td> 274 <td>French text for <code>app_name</code>, <code>text_a</code> and 275<code>text_b</code>; French flag</td> 276 <td>French text for <code>app_name</code>, <code>text_a</code> and 277<code>text_b</code>; Canadian flag</td> 278 <td>-</td> 279 <td>-</td> 280 <td>French text for <code>app_name</code>, <code>text_a</code> and 281<code>text_b</code>; British flag</td> 282 </tr> 283 <tr> 284 <th scope="row">Japanese</th> 285 <td>-</td> 286 <td>-</td> 287 <td>-</td> 288 <td>-</td> 289 <td>Japanese text for <code>text_a</code> and <code>text_b</code>; Japanese 290flag</td> 291 <td>-</td> 292 <td>Japanese text for <code>text_a</code> and <code>text_b</code>; British 293flag</td> 294 </tr> 295 <tr> 296 <th scope="row">Other Language</th> 297 <td>-</td> 298 <td>-</td> 299 <td>-</td> 300 <td>-</td> 301 <td>-</td> 302 <td>-</td> 303 <td> British English text; British flag <em>(default)</em></td> 304 </tr> 305</table> 306 307<p class="note"> Note that other behaviors are possible; for example, the 308application could support Canadian English or U.S. English text. But given the 309small amount of text involved, adding more versions of English would not make 310this application more useful.</p> 311 312<p>As shown in the table above, the plan calls for five flag icons in addition 313to the British flag that is already in the <code>res/drawable/</code> folder. It 314also calls for three sets of text strings other than the text that is in 315<code>res/values/strings.xml</code>.</p> 316 317<p>Table 2 shows where the needed text strings and flag icons will go, and 318specifies which ones will be loaded for which locales. (For more about the 319locale codes, <em></em>see <a 320href="{@docRoot}guide/topics/resources/resources-i18n.html#AlternateResources"> 321Alternate Resources</a>.)</p> 322<p class="caption" id="table2">Table 2</p> 323 324<table border="1" cellspacing="0" cellpadding="5"> 325 <tr> 326 <th scope="col">Locale Code</th> 327 <th scope="col">Language / Country</th> 328 <th scope="col">Location of strings.xml</th> 329 <th scope="col">Location of flag.png</th> 330 </tr> 331 <tr> 332 <td><em>Default</em></td> 333 <td>English / United Kingdom</td> 334 <td>res/values/</td> 335 <td>res/drawable/</td> 336 </tr> 337 <tr> 338 <td>de-rDE</td> 339 <td>German / Germany</td> 340 <td>res/values-de/</td> 341 <td>res/drawable-de-rDE/</td> 342 </tr> 343 <tr> 344 <td>fr-rFR</td> 345 <td>French / France</td> 346 <td>res/values-fr/</td> 347 <td>res/drawable-fr-rFR/</td> 348 </tr> 349 <tr> 350 <td>fr-rCA</td> 351 <td>French / Canada</td> 352 <td>res/values-fr/</td> 353 <td>res/drawable-fr-rCA/</td> 354 </tr> 355 <tr> 356 <td>en-rCA</td> 357 <td>English / Canada</td> 358 <td><em>(res/values/)</em></td> 359 <td>res/drawable-en-rCA/</td> 360 </tr> 361 <tr> 362 <td>ja-rJP</td> 363 <td>Japanese / Japan</td> 364 <td>res/values-ja/</td> 365 <td>res/drawable-ja-rJP/</td> 366 </tr> 367 <tr> 368 <td>en-rUS</td> 369 <td>English / United States</td> 370 <td><em>(res/values/)</em></td> 371 <td>res/drawable-en-rUS/</td> 372 </tr> 373</table> 374 375<p class="note"><strong>Tip: </strong>A folder qualifer cannot specify a region 376without a language. Having a folder named <code>res/drawable-rCA/</code>, 377for example, will prevent the application from compiling. </p> 378 379<p>At run time, the application will select a set of resources to load based on the locale 380that is set in the user's device. In cases where no locale-specific resources 381are available, the application will fall back on the defaults. </p> 382 383<p>For example, assume that the device's language is set to German and its 384location to Switzerland. Because this application does not have a 385<code>res/drawable-de-rCH/</code> directory with a <code>flag.png</code> file in it, the system 386will fall back on the default, which is the UK flag located in 387<code>res/drawable/flag.png</code>. The language used will be German. Showing a 388British flag to German speakers in Switzerland is not ideal, but for now we will 389just leave the behavior as it is. There are several ways you could improve this 390application's behavior if you wanted to:</p> 391 392<ul> 393 <li>Use a generic default icon. In this application, it might be something 394that represents Shakespeare. </li> 395 <li>Create a <code>res/drawable-de/</code> folder that includes an icon that 396the application will use whenever the language is set to German but the location 397is not Germany. </li> 398</ul> 399 400 401<h2 id="localize">Localize the Application</h2> 402 403<h3 id="localize_strings">Localize the Strings</h3> 404 405<p>The application requires three more <code>strings.xml</code> files, one 406each for German, French, and Japanese. To create these resource files within 407Eclipse:</p> 408 409<ol> 410<li>Select <strong>File</strong> > <strong>New</strong> > <strong>Android 411XML File</strong> to open the New Android XML File wizard. You can also open 412the wizard by clicking its icon in the toolbar:<br /> 413<img src="{@docRoot}images/hello_l10n/xml_file_wizard_shortcut.png" 414alt="file_wizard_shortcut" width="297" 415height="90" style="margin:15px"></li> 416 <li>Select L10N for the Project field, and type <code>strings.xml</code> into 417the File field. In the left-hand list, select Language, then click the right arrow.<br> 418<img src="{@docRoot}images/hello_l10n/xml_wizard1.png" alt="res_file_copy" width="335" 419height="406" style="margin:15px"></li> 420 <li>Type <code>de</code> in the Language box and click Finish.<br> 421 <img src="{@docRoot}images/hello_l10n/xml_wizard2.png" alt="res_file_copy" width="306" 422height="179"> 423<p>A new file, <code>res/values-de/strings.xml</code>, now appears among the project 424files.</p></li> 425<li>Repeat the steps twice more, for the language codes <code>fr</code> and 426 <code>ja</code>. 427Now the project includes these new skeleton files: <br /> 428 <code>res/<strong>values-de</strong>/strings.xml</code><br /> 429 <code>res/<strong>values-fr</strong>/strings.xml</code><br /> 430 <code>res/<strong>values-ja</strong>/strings.xml</code><br /> 431 </li> 432 <li>Add localized text to the new files. To do 433this, open the <code>res/values-<em><qualifier></em>/strings.xml</code> files and 434replace the code as follows:</li> 435</ol> 436 437<table border="0" cellspacing="0" cellpadding="0"> 438 <tr> 439 <th scope="col">File</th> 440 <th scope="col">Replace the contents with the following code:</th> 441 </tr> 442 <tr> 443 <td><code>res/values-de/strings.xml</code></td> 444 <td><pre><?xml version="1.0" encoding="utf-8"?> 445<resources> 446 <string name="app_name">Hallo, Lokalisierung</string> 447 <string name="text_a">Soll ich dich einem Sommertag vergleichen,</string> 448 <string name="text_b">Der du viel lieblicher und sanfter bist?</string> 449</resources></pre></td> 450 </tr> 451 <tr> 452 <td><code>res/values-fr/strings.xml</code></td> 453 <td><pre><?xml version="1.0" encoding="utf-8"?> 454<resources> 455 <string name="app_name">Bonjour, Localisation</string> 456 <string name="text_a">Irai-je te comparer au jour d'été?</string> 457 <string name="text_b">Tu es plus tendre et bien plus tempéré.</string> 458</resources> </pre></td> 459 </tr> 460 <tr> 461 <td><code>res/values-ja/strings.xml</code></td> 462 <td> 463<pre><?xml version="1.0" encoding="utf-8"?> 464<resources> 465 <string name="text_a">あなたをなにかにたとえるとしたら夏の一日でしょうか?</string> 466 <string name="text_b">だがあなたはもっと美しく、もっとおだやかです。</string> 467</resources></pre></td> 468 </tr> 469</table> 470 471<p class="note"><b>Tip:</b> In the 472<code>values-<em><qualifier></em>/strings.xml</code> files, you only need to 473include text for strings that are different from the default strings. For 474example, when the application runs on a device that is configured for Japanese, 475the plan is for <code>text_a</code> and <code>text_b</code> to be in Japanese 476while all the other text is in English, so 477<code>res/values-ja/strings.xml</code> only needs to include <code>text_a</code> 478and <code>text_b</code>.</p> 479 480<h3 id="localize_images">Localize the Images</h3> 481 482<p>As shown in <a href="#table2">Table 2</a>, the application needs six more 483drawable folders, each containing a <code>flag.png</code> icon. Add the needed 484icons and folders to your project:</p> 485 486<ol> 487 <li>Save this <a href="../../../images/hello_l10n/drawable-de-rDE/flag.png">German flag icon</a> 488as <code>res/drawable-de-rDE/flag.png</code> in the application's project 489workspace. 490 <p>For example:</p> 491 <ol> 492 <li>Click the link to open the flag image.</li> 493 <li>Save the image in 494<code><em>your-workspace</em>/HelloL10N/res/drawable-de-rDE/</code> .</li> 495 </ol> 496 </li> 497 <li>Save this <a href="../../../images/hello_l10n/drawable-fr-rFR/flag.png">French flag icon</a> 498as <code>res/drawable-fr-rFR/flag.png</code> in the application's project 499workspace. </li> 500 <li>Save this <a href="../../../images/hello_l10n/drawable-fr-rCA/flag.png">Canadian flag icon</a> 501as <code>res/drawable-fr-rCA/flag.png</code> in the project workspace. </li> 502 <li>Save the <a href="../../../images/hello_l10n/drawable-en-rCA/flag.png">Canadian flag icon</a> 503again, this time as <code>res/drawable-en-rCA/flag.png</code> in the project 504workspace. (Why not have just <em>one</em> folder that contains the Canadian 505flag? Because a folder qualifer cannot specify a region without a language. 506You cannot have a folder named <code>drawable-rCA/</code>; instead you must 507create two separate folders, one for each of the Canadian languages represented 508in the application.)</li> 509 <li>Save this <a href="../../../images/hello_l10n/drawable-ja-rJP/flag.png">Japanese flag icon</a> 510as <code>res/drawable-ja-rJP/flag.png</code> in the project workspace. </li> 511 <li>Save this <a href="../../../images/hello_l10n/drawable-en-rUS/flag.png">United States flag 512icon</a> as <code>res/drawable-en-rUS/flag.png</code> in the project workspace. 513 </li> 514</ol> 515 516<p>If you are using Eclipse, refresh the project (F5). The new 517<code>res/drawable-<em><qualifier></em>/</code> folders should appear in the 518project view. </p> 519 520 521<h2 id="test_localized">Run and Test the Localized Application</h2> 522 523<p>Once you've added the localized string and image resources, you are ready to 524 run the application and test its handling of them. To change the locale 525 on a device or in the emulator, use the Settings 526application (Home > Menu > Settings > Locale & text > Select 527locale). Depending on how a device was configured, it might not offer any 528alternate locales via the Settings application, or might offer only a few. The 529emulator, on the other hand, will offer a selection of all the locales that are 530available in the Android system image. </p> 531 532<p>To set the emulator to a locale that is not available in the system image, 533use the Custom Locale application, which is available in the Application 534tab:</p> 535 536<p><img src="{@docRoot}images/hello_l10n/custom_locale_app.png" alt="custom locale app" width="163" 537height="158" style="margin-left:15px"></p> 538 539<p>To switch to a new locale, long-press a locale name:</p> 540 541<p><img src="{@docRoot}images/hello_l10n/using_custom_locale.png" alt="using custom locale" 542width="512" height="299" style="margin-left:15px"></p> 543 544<p>For a list of locales available on different versions of the Android platform, 545refer to the platform notes documents, listed under "Downloadable SDK Components" 546in the "SDK" tab. For example, <a 547href="{@docRoot}sdk/android-2.0.html#locs">Android 2.0 locales</a>.</p> 548 549<p>Run the application for each of the expected locales, plus one unexpected 550locale. Here are some of the results you should see:</p> 551 552<table border="0" cellspacing="0" cellpadding="05"> 553 <tr> 554 <th scope="col">Locale</th> 555 <th scope="col">Opening screen of application</th> 556 </tr> 557 <tr> 558 <td>German / Germany 559 <br />Specifically supported by the Hello, L10N application.</td> 560 <td><img src="{@docRoot}images/hello_l10n/german_screenshot.png" alt="custom locale app" 561width="321" height="175" align="right" 562style="margin-left:10px;margin-right:20px"></td> 563 </tr> 564 <tr> 565 <td>French / Canada 566 <br />Specifically supported by the Hello, L10N application.</td> 567 <td><img src="{@docRoot}images/hello_l10n/frenchCA_screenshot.png" alt="custom locale app" 568width="321" height="175" align="right" 569style="margin-left:10px;margin-right:20px"></td> 570 </tr> 571 <tr> 572 <td>German / Switzerland 573 <br />Only the language is specifically supported by 574the Hello, L10N application.</td> 575 <td><img src="{@docRoot}images/hello_l10n/germanCH_screenshot.png" alt="custom locale app" 576width="321" height="175" align="right" 577style="margin-left:10px;margin-right:20px">`</td> 578 </tr> 579 <tr> 580 <td>Japanese 581 <br />Specifically supported by the Hello, L10N application. 582 </td> 583 <td><img src="{@docRoot}images/hello_l10n/japanese_screenshot.png" alt="custom locale app" 584width="321" height="220" align="right" 585style="margin-left:10px;margin-right:20px">`</td> 586 </tr> 587 <tr> 588 <td>Romansh / Switzerland (custom locale <code>rm_CH</code>) 589 <br />Not specifically supported by the Hello, L10N 590application, so the application uses the default resources.</td> 591 <td><img src="{@docRoot}images/hello_l10n/romanshCH_screenshot.png" alt="custom locale app" 592width="321" height="175" align="right" 593style="margin-left:10px;margin-right:20px"></td> 594 </tr> 595</table> 596