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