Skip to main content

Implementing Localization

1. Creating String Resources

Resource Name Value Description
strings.xml <string name="app_name">MyApp</string> Default string resource file
strings.xml (localized) <string name="app_name">MiAplicación</string> Localized string resource file for Spanish

Example: Define a localized string resource

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="welcome_message">Welcome to our app!</string>
    <string name="user_greeting">Hello, %1$s!</string>
</resources>
Note: Use %1$s for string placeholders and %d for integers in localized strings.

Example: Using string resources in Kotlin

val welcomeMessage = getString(R.string.welcome_message)
val userGreeting = getString(R.string.user_greeting, userName)

2. Adding Language Qualifiers

Qualifier Language Notes
values en English (default)
values es Spanish
values fr French
values de German
values ja Japanese
values ko Korean
values pt Portuguese
values ru Russian
values zh Chinese (Simplified)
values zh-rTW Chinese (Traditional)

Example: Language Resource Directory Structure


values/
  strings.xml
values-es/
  strings.xml
values-fr/
  strings.xml
values-ja/
  strings.xml
values-zh/
  strings.xml

3. Using Plurals for Quantities

Resource Description Usage
plurals Resource type for handling pluralized strings based on quantity <plurals name="numberOfItems">

Example: Defining Plurals in XML

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <plurals name="numberOfItems">
        <item quantity="zero">No items</item>
        <item quantity="one">One item</item>
        <item quantity="two">Two items</item>
        <item quantity="few">{count} items</item>
        <item quantity="many">Many items</item>
        <item quantity="other">{count} items</item>
    </plurals>
</resources>

Example: Using Plurals in Kotlin

val count = 5
val message = getString(R.plurals.numberOfItems, count, count)
// Result: "5 items"
Note: The quantity attribute in <item> tags corresponds to Android's plural rules, which vary by language.

4. Formatting Dates and Times

Method Description Example
formatDate() Formats a date using the specified pattern
val formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
val date = LocalDate.now()
val formatted = date.format(formatter)
formatTime() Formats a time using the specified pattern
val formatter = DateTimeFormatter.ofPattern("HH:mm:ss")
val time = LocalTime.now()
val formatted = time.format(formatter)
formatDateTime() Formats a date and time using the specified pattern
val formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
val dateTime = LocalDateTime.now()
val formatted = dateTime.format(formatter)

Example: Formatting with Locale

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.Locale

val dateTime = LocalDateTime.now()
val formatter = DateTimeFormatter.ofPattern("d MMM yyyy, HH:mm", Locale.FRENCH)
val formattedDate = dateTime.format(formatter)
Note: Use Locale.getDefault() to get the current locale.
Warning: Ensure that date/time patterns match the expected format for the target locale.

5. Formatting Numbers and Currency

Feature Description Example
Number formatting Formats numbers according to locale-specific rules.
val number = 1234567.89
val formatter = NumberFormat.getInstance()
val formatted = formatter.format(number)
Currency formatting Formats currency values with locale-specific symbols and rules.
val amount = 1234.56
val currency = Currency.getInstance("USD")
val formatter = NumberFormat.getCurrencyInstance()
val formatted = formatter.format(amount)

Example: Formatting Numbers in Different Locales

val number = 1234567.89
val usFormatter = NumberFormat.getInstance(Locale.US)
val deFormatter = NumberFormat.getInstance(Locale.GERMANY)
val frFormatter = NumberFormat.getInstance(Locale.FRANCE)

println(usFormatter.format(number)) // 1,234,567.89
println(deFormatter.format(number)) // 1.234.567,89
println(frFormatter.format(number)) // 1 234 567,89

Example: Formatting Currency in Different Locales

val amount = 1234.56
val usFormatter = NumberFormat.getCurrencyInstance(Locale.US)
val deFormatter = NumberFormat.getCurrencyInstance(Locale.GERMANY)
val frFormatter = NumberFormat.getCurrencyInstance(Locale.FRANCE)

println(usFormatter.format(amount)) // $1,234.56
println(deFormatter.format(amount)) // 1.234,56 €
println(frFormatter.format(amount)) // 1 234,56 €

6. Using RTL Support

Property Description Values
android:supportsRtl Enables RTL layout support for the app true or false
android:layoutDirection Defines the layout direction for a view or layout ltr, rtl, inherit
android:textDirection Defines the text direction for a view or layout ltr, rtl, inherit

Example: Setting RTL Support in Manifest

<application
    android:supportsRtl="true"
    ... >

Example: Using Layout Direction in XML

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layoutDirection="rtl"
    ... >

Example: Setting Text Direction Programmatically

val textView = findViewById<TextView>(R.id.textView)
textView.setTextDirection(View.TEXT_DIRECTION_RTL)
Note: RTL support requires proper handling of layout and text direction in UI components to ensure correct rendering in right-to-left languages like Arabic or Hebrew.

7. Translating String Resources

Resource Type Description
strings.xml XML Main resource file for string translations
strings.xml (localized) XML Translated versions in language-specific folders

Example: Translating a String Resource

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="welcome_message">Welcome to our app!</string>
</resources>

Example: Translated String Resource (Spanish)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="welcome_message">¡Bienvenido a nuestra aplicación!</string>
</resources>
Note: Android automatically selects the appropriate strings.xml based on device language settings.

Localization Workflow

  • Create base strings.xml in res/values/
  • Create localized versions in res/values-xx/ where xx is language code
  • Use @string/welcome_message in layouts to reference translated strings

8. Testing Different Locales

Example: Setting Locale in Android Emulator

adb shell setprop persist.sys.locale fr-FR
Locale Code Notes
French (France) fr-FR Default for France
German (Germany) de-DE Default for Germany
Spanish (Spain) es-ES Default for Spain
Japanese (Japan) ja-JP Default for Japan
Note: Use Locale.setDefault() to change the app's default locale programmatically.
Warning: Ensure all string resources are properly localized before testing.

Workflow: Testing Locale Changes

  1. Set device/emulator locale to target language
  2. Rebuild and reinstall app
  3. Verify all UI elements adapt to new language
  4. Check for text overflow or layout issues

9. Handling Per-App Language Preferences

Property Value Description
locale Locale.getDefault() Current app locale used for resource lookup
resources.configuration.locale Configuration.locale Current configuration locale for UI

Example: Setting App Locale Programmatically

import android.content.res.Configuration
import java.util.Locale

fun setAppLocale(context: Context, languageCode: String) {
    val locale = Locale(languageCode)
    val config = Configuration(context.resources.configuration).apply {
        setLocale(locale)
    }
    context.createConfigurationContext(config)
}
Note: Changes to locale require restarting the activity or using recreate() to reflect in UI.

Key Points

  • Use Locale.setDefault() to change the default locale for the app
  • Update Configuration.locale to reflect changes in UI and resources
  • App locale changes do not automatically update the UI; you must manually refresh or restart the activity

10. Using Grammatical Inflection API

Property Description Example
pluralize() Pluralizes a noun based on the grammatical context val plural = "cat".pluralize() // "cats"
singularize() Converts a plural noun to its singular form val singular = "cats".singularize() // "cat"
ordinalize() Converts a number to its ordinal form (e.g., 1st, 2nd) val ordinal = 3.ordinalize() // "3rd"

Example: Using pluralize in Android

import java.util.Locale

val locale = Locale.getDefault()
val pluralForm = "item".pluralize(locale) // "items" in English
Note: The pluralize() function requires the androidx.core library or a third-party library like inflector.
Warning: Grammatical inflection APIs may not support all languages or complex rules. Always test in target locales.

Was this article helpful?