Android & Kotlin Tutorials

Learn Android development in Kotlin, from beginner to advanced.

Android Localization: Getting Started

Android runs on many devices in many regions. To reach the most users, your app should handle content to reflect the locales where your app is used.

Version

  • Kotlin 1.3, Android 8.0, Android Studio 3.4

When building apps, it’s important to think about your users. After all, they’re the ones who’ll be using your apps!

You should consider if your app would benefit from multi-lingual support to appeal to the widest range of users. You might also find that different images or layouts work better for different locales.

In this tutorial you’ll learn how to:

  • Support multiple languages.
  • Test your layouts for different languages, including Right-to-Left languages.
  • Add resources for different locales.
Note: This tutorial assumes a basic knowledge of Android and Android Studio. If you’re new to Android development or don’t already have Android Studio installed, refer to these Beginning Android Development tutorials.

Getting Started

Start by downloading the starter project using the Download Materials button at the top or bottom of this tutorial.

Open the project in Android Studio and get familiar with the files. Then build the project and run it on a device to see how the app looks.

The app is a simple avatar generator. The user can customize their avatar by selecting hair, clothes and shoe options from four Spinners. The Share button brings up a Share Sheet so the user can share a text description of their customized avatar through an app of their choice.

Note: A Spinner is an Android component which works in a similar way to a drop down list. Check out the official Android documentation for more details.

This starter project was built to appeal to an American audience. It displays options which make sense to those familiar with American English. There’s also a fun illustration which is very America-centric which displays the American flag.

In its current state, this app is fine for an American audience. But suppose you wanted to put this app in front of a British audience. The pants option takes on quite a more risque meaning!

You should add locale support for these users before making the app available to them. This tutorial will show you how to do that.

Localization

Before you dive in, keep the following things in mind. Your life will be much easier if you decide to localize later on.

  • Keep your strings in a strings.xml file: Instead of using hardcoded strings, which are added directly where needed in the code, define each string as a key value pair in a separate resource file called strings.xml. Here you assign an id to each string which can be referenced wherever you want to use that text in your project.

    This means all your strings are easy to find. You’ll see how that makes adding translations straightforward in a minute.

    This file should be kept in the values directory in the resources section of your project. It’ll be your default strings file.

  • Try to avoid images containing text: If you decide to localize, you’ll need to add a new image asset for each language, increasing the size of your APK. It’s better to keep all text as strings where possible.

Once you’ve developed your app with all your strings in the strings.xml file, adding localization support is quite straightforward. The Android system does much of work for you.

How the System Knows What to Display

When a user opens your app, the system uses the device locale to determine in which directory it can find the resources to display. Directories contain qualifiers in their names. The system uses these qualifiers to select the correct directory for each locale.

It’s important to provide a default resource file for each kind of resource, such as strings and drawables. If the system can’t find a directory to match the configuration of the device, then it’ll fall back to the default file. For example, if the user’s primary device locale is Spanish but there is no values-es directory present in the project, it’ll use the default.

If the system can’t find a default value to map a resource id to, then your app will crash. So, make sure to always define a default for all of your resources. The default file will live in a resource directory without any qualifiers in the name.

For each new language you wish to support, you’ll need to put a new strings.xml file containing your translations inside a new resource directory with a locale qualifier. The new file should contain translated strings paired with the same id used in the default file, as this id is the one which will be referred to in the code.

Don’t worry if this is a bit confusing at the moment. You’ll go through this step-by-step in the next section when you add British English translations to the sample app.

The following table, taken from the developer.android.com documentation, shows an example of the resolution strategy Android uses for versions greater than Android 7.

Here, the user has their device’s primary language set to fr_CH, but the app hasn’t explicitly supported this language. Failing to find an explicit match, the system looks for directories supporting other regions of the language. In this case, it found and displayed fr_FR.

If this directory hadn’t been present, it would’ve fallen back to the default. The default locale for Android devices is usually en-rUS.

For more explanation and examples of system resource resolution, consult the official Android documentation.

That seems like quite a lot to take in at once, but in practice it’s a fairly straightforward process. Time to get started localizing your app!

Adding Strings Files for Other Languages

In the sample project, open strings.xml. Most of the strings make sense on both sides of the pond. But, there are some which you should translate for a British audience:

<string name="top_sweater">Sweater</string>
<string name="bottom_pants">Pants</string>
<string name="shoes_sneakers">Sneakers</string>

Creating a New Resource Directory

Before moving on, make sure you have Android Studio set to the Project view, and not Android. This will let you see all directories as they appear on disk. That’ll come in handy when when you add new resource files later.

Create a new resource directory to store the GB translations. In Android Studio, navigate in the Project panel to the res folder. Right click on it, then choose New ▸ Android Resource Directory.

This opens the New Resource Directory window. From there, you can select the resource type and qualifiers you want to create. For localization of strings, add a new directory with a values resource type and a Locale qualifier.

Select Locale from the list of qualifiers and move it into the Chosen qualifiers section by pressing the >> button in the middle of the window. This will open new panels showing all the available options for your chosen qualifier. Select en: English as the language and GB: United Kingdom as the specific region.

Notice the directory name has been pre-filled with the resource type and qualifiers you selected. Don’t change the directory name because this format is required by the system to find your resources.

Press OK to confirm and close the window. You’ll see a new values directory appear in the Project panel named values-en-rGB. Put the strings file that contains all the translations for British users in this directory.

Creating a New Strings File

Create a new strings.xml file in this directory by right clicking on the directory. Then choose New ▸ Values resource file.

In the window that pops up, enter the name strings.xml and press OK. It’s important to give this file the same name as your default strings file, in the values directory, so the system can swap them out as needed.

You’ll see the new strings.xml has a little Union Jack to help you identify it in the Project panel and open file tabs.

In this new file, you can add any translations you want to show when the device is set to British English. Remember, you don’t need to provide translations for every string in the app here. As long as the string is defined in the default strings.xml, any strings which haven’t been defined in the British file will fall back to their default value.

Add the following translations to the new strings.xml between the resources tags. The string names exactly match the ones already defined in the default file. Only the value has been translated.

<string name="top_sweater">Jumper</string>
<string name="bottom_pants">Trousers</string>
<string name="shoes_sneakers">Trainers</string>

And that’s it— you’ve added translations to your app! But how do you know if it worked? You can test in Android Studio before you run it on a device.

Previewing in Android Studio

Open activity_main.xml in Android Studio. At the bottom of the file, make sure you’ve selected the Text tab so you can see the xml code.

You’ll see a Preview panel on the right of the screen. You may need to expand it from the side panel if isn’t already.

In the Preview pane’s toolbar there’s a Locale for Preview dropdown which shows Default (en-us). This is your default strings file.

Now that the project has multiple locale directories, you can change this option in the preview to see how it looks. Select English (en) in United Kingdom (GB) from the dropdown menu.

One snag— nothing’s changed!

The three translations were all for values used in the Spinners. These get added to the code programmatically rather than in the xml file. The xml layout file doesn’t know about these values and can’t populate them in the preview.

For the sake of this tutorial, add another string translation to your en-rGB/strings.xml for the title at the top of the screen. This value gets assigned to the TextView in the xml code so Android Studio knows how to populate it for the preview.

This translation is a temporary addition for testing purposes. You’re not going to ship with it. So, for now, add a string you’ll recognize to show it worked in preview:

<string name="title_select_characteristics">This is British English</string>

Go back to activity_main.xml preview. With English(en/GB) still selected, you should now see the temporary title in preview. Congratulations, it worked!

This preview is useful because it shows you how your layouts look with different values. Some languages may have longer or shorter translations than your defaults. This is a good way to catch any problems with your layouts early on.

Before you forget, go back and remove the temporary string you added.

Testing on an Emulator

Next you should test on an emulator. Build and run the app. Initially, nothing should look any different than when you first ran this project.

The emulator is like a real device. You can change the primary language in the same way you would on your Android phone.

On the emulator, open the Settings app and navigate to System ▸ Languages & input ▸ Languages. If it’s not already there, add English (United Kingdom) as a language to your Language Preferences. Move it to the top of the list.

Reopen the sample app in the emulator. You’ll now see the spinner options have changed to display the translated values.

The app is now pulling in the translated strings from the GB resource directory to comply with the primary device language set by the user. Your app now supports multiple locales!

Tips for Getting Good Translations

Knowing how to support multiple languages in your app is all well and good. But to provide that support to your users, you need to actually get translations for the text in your app.

Unless you’re a master linguist, it’s unlikely you can translate all your strings into all the languages you want to provide support for. So, you’ll need to find someone who can translate it for you.

Maybe you have international friends you trust to provide local translations for you. Failing that, there are many companies that provide translation services.

However you obtain your translations, in most cases, you’re going to send them across strings.xml. So, the more context you can provide about where those strings are used, the better.

Some of the words will be straightforward to translate. Others may have different translations with different meanings depending on the context in which they’re used.

In strings.xml, you should provide comments with the context for each string. Look in the sample app and you’ll see there are comments providing context about what the strings are for and where they’re used in the app.

Other things to consider:

  • Untranslatable strings: If you don’t want a string to be translated, you can add translatable=”false” to the string declaration after you define the name.
  • Formatters: If you’re not sure what formatters are, check the formatting and styling documentation. With the broad range of regional support Android provides, there can be differences in formats for things like dates and times within the same locale.

    You should use formatted strings rather than hardcoded values or method calls to convert numbers or dates to strings in your app logic. This lets the system format the numbers with the correct set of digits according to the region. Read more about this here.

  • Positional string arguments: For some locales, the order of the parameters provided may differ. So, you should annotate the ordering in your strings file. There’s an example of this kind of annotation in the sample app share_text string: I just generated a cool character with %1$s hair, wearing a %2$s, %3$s and %4$s!

Right-To-Left Languages

Supporting multiple languages can sometimes require extra consideration. Some languages, for instance Arabic or Hebrew, read from right-to-left, RTL, rather than left-to-right, LTR, like the English languages this tutorial has covered so far.

Mirroring UI

To support RTL languages in your app, you should test your layouts to ensure your UI functions as intended when mirrored.

Note: See the Android design documentation for more information about which elements of your UI you should mirror in RTL layouts.

For simple layouts, following Android best practices when creating your layouts should go a long way. You should always build according to best practices to minimize the effort required to make changes down the line. Key things to keep in mind are:

  • Always use xml attributes referring to the start and end of views instead of left and right, unless your layout strictly requires this for all locales. If the device is set to RTL, the right hand side of the screen is considered the start instead of the left. So, these attributes help display your layout as expected when mirrored.

    The left hand side of the screen remains on the left even when mirrored. So the layout doesn’t change when mirrored when you use this attribute to position a view.

  • Don’t restrict both android:layout_width and android:layout_height of a TextView to fixed values. Words and phrases may differ in length when translated into different languages. The text may be cut off if you have fixed your view to a size which is too small.

    It’s most common to set either android:layout_width or android:layout_height to wrap_content to allow it to wrap to the size it needs. If your layout really does need fixed sizes, you should look at utilizing Autosizing TextViews.

  • Consider using ConstraintLayout to build your layout. Features such as Barriers are particularly useful for allowing the UI to adapt to strings of different lengths when lining up other views. Refer to this tutorial if you want to learn more about ConstraintLayout.

Creating Custom Layouts for Locales

In most cases, following the above tips should enable you to use the same layout file to support both LTR and RTL. But for complex layouts or particularly custom UIs, you may wish to create separate layout files to optimize layouts for different layout directions.

Store the RTL optimized layouts in a resource directory named layout-ldrtl, keeping the layout file name the same as the one you wish to replace for RTL configurations. You can create this directory in Android Studio the same way you created a new directory for different String locales earlier.

This time, select layout as the resource type and use Layout Direction as the qualifier. Pick RTL as the layout direction for this directory.

Testing for RTL Locales

The sample project currently doesn’t contain any RTL language files. But you can still test to see if the app is ready to support them.

First, confirm the app has enabled RTL support by checking in AndroidManifest.xml that application contains android:supportsRtl=”true”.

While developing your layout in Android Studio, you can use the layout preview pane to quickly see how it would look in RTL mode.

Earlier, you learned how to view the localized strings in the layout preview. You might have noticed the Right to Left preview in the same menu. Toggling Preview Right to Left in this menu mirrors the layout in the preview.

Once you’re happy with your layout, you should also test on an Android emulator. Luckily, the developer options on the device have some useful tools for testing different types of languages. So, you can test your layout in RTL mode without learning to read Arabic first!

Developer Options

If you haven’t already, enable developer options on your emulator. To do this, open the Settings app and find the Build number.

This number’s location can vary for different devices, but you’ll likely find it at System ▸ About emulated device. Tap the row containing the build number seven times.

Congratulations, you’re now a developer! :]

With your shiny new developer status, you now have access to Developer Options, a new menu in the System area of Settings.

Click the Developer options menu and ensure it’s turned on.

Pseudolocales

Next, enable pseudolocales for your debug builds. In the sample project you need to add a new configuration to your app build.gradle. Add the following code inside the buildTypes section to add a new debug build type and enable pseudolocales.

debug {
  pseudoLocalesEnabled true
}

Your build.gradle should look like this:

Since you edited build.gradle, you’ll need to sync. Press the Sync Now button in the banner at the top of the file. Then build and run the app. You’re ready to test on the emulator.

With the latest debug version of the app loaded on the device, all that’s left to do to test for RTL locales is to change the device language to a pseudolocale. There are two available pseudolocales:

  • English([XA]): This is a LTR locale which reads like English, but adds accents to characters and expands text to aide with exposing layout issues.
  • Arabic([XB]): This is an RTL locale. It triggers the device to go into mirrored UI mode to better support the RTL text direction. It also reverses the characters of English strings to help mimic an RTL locale. This helps expose layouts that aren’t mirrored properly and strings that can’t be translated or have other punctuation or number character ordering issues.

You can find the pseudolocales in the Languages section of Settings.

Select cibarA([XB]) from the languages list and move it to the top of your language preferences. The device will automatically switch to RTL mode. You’ll also see that the system string character ordering is reversed to emulate a RTL directional locale.

Open the app and you’ll see how it looks in a RTL locale.

The app looks good mirrored and is ready to support RTL languages!

Drawables

You’ve already covered a lot in this tutorial, but there’s still one thing left to address. The app still shows the US flag to users of all locales!

By now, you’ve probably got the hang of adding resource files for different configurations, but here are the steps one more time.

Create a new resource directory where you’ll add a new image to display to British users. As before, right click on the res package and select New ▸ Android resource directory. You need to create a new drawable folder for the en-GB locale. Select drawable as the resource type, locale as the qualifier, en:English as the language and GB:United Kingdom as the region.

When you add a new image to this directory, you’ll need to make sure to save it with the same name as the default image. That way, when the device switches locale it can use the same filename referenced in the code to get the image.

For the sample app, you should save the new image with the filename img_flag.png. You can either save this image directly into the folder using a File Explorer on your machine, or drag and drop the image file into the folder in Android Studio.

Feel free to find your own image to use here. But here’s a cute little Union Jack in the same style as the existing US flag you can use. Right click and save it into your new GB resource directory.

You’ve now added a localized drawable. Build and run the app again. Change your emulator or device’s primary language to English (United Kingdom) and open the app again to see the new image displayed on the screen.

Localization Checklist

Google provides much of support for developers through the Google Play store. For localization, they’ve provided a handy Localization Checklist to help get your app ready to support new locales.

The checklist contains useful tips to ensure you haven’t forgotten anything and covers the whole process from start to finish. It’s a very useful resource and worth checking out both before and after you decide to target multiple locales.

If you’ve covered everything in that checklist, you should be ready to go!

Where to Go From Here?

Download the final project using the Download Materials button at the top or bottom of this tutorial.

As you’ve seen, there are many things to consider when localizing your apps to target different audiences. But Android makes it fairly simple to add all these different configurations to your project through resource directories.

If you want to try increasing localization support further in your apps, look at providing alternative resources for other aspects of your app, such as custom layouts, multiple currencies or audio files. As a starting point for adding audio files, read the documentation on MediaPlayer.

The skills you have gained in this tutorial for making new resource files with qualifying identifiers can help you make your app more robust in other areas, too. Try playing around with providing other qualifiers for resource files, such as screen orientation or size. You’ll find a list of all available qualifiers here.

Hopefully, this tutorial covered enough to get you started on the road to supporting as many users as possible in ways that appeal to them. If you have any comments or questions, use the forum below.

Add a rating for this content

Contributors

Comments