Anatomy of an Android App

Sep 10 2024 · Kotlin 1.9.23, Android 14, Android Studio Iguana

Lesson 02: Use Android Resources

Demo

Episode complete

Play next episode

Next
Transcript

Managing Strings in Your App

One of the most important elements of any app is the text, or strings, displayed on the screen. As you advance in your Android development career, you’ll want to master the ins and outs of using strings.

For instance, your app uses English labels, but that doesn’t mean it’s the only language your app can support. Supporting multiple languages in your app means people can use it even if they don’t understand English. You should consider supporting multiple languages when putting your app on the Google Play Store.

Build and run the app; you’ll see a simple blank screen with just the text “Hello Android!”. You’ll update this text.

Open MainActivity.kt, and in the function Greeting, change the text value “Hello” to “Hi,”. Build and run; you’ll see the text on the app has changed.

This works well if you’re targeting only English-speaking users. But how would you support one, two, or even a dozen other languages?

The answer to this is String resources.

In the Project navigator, expand res/values, and open strings.xml. You’ll see a file with the following content:

<resources>
  <string name="app_name">Kodeco Chat</string>
</resources>

strings.xml gives you a place to store all the strings used in your app. This helps to keep strings from being sprinkled throughout your code. Using strings.xml from the beginning is a better approach than adding it after completing the project, which would involve changing hard-coded text in many places.

strings.xml also makes it easy to add support for another language. Rather than hunting through the entire project to change all the strings, you copy the file and change it to hold the language translations of your choice.

For Kodeco Chat, you’ll use this file to keep your English text in a separate location.

Also, note this notification in Android Studio, “Edit translations for all locales in the translations editor.” You can click the link to open the translations editor. If you don’t see this notificaiton, you can also right-click on the Strings.xml file and select Open Translations Editor from the context menu.

The Translations Editor provides a consolidated and editable view of all of your default and translated string resources. You can open it now to see that it offers an alternative method to editing your string resources files. Currently there is only one value. For now, we are going to edit the strings.xml file directly.

Update strings.xml so it contains all the strings needed for your app:

<resources>
  <string name="app_name">Kodeco Chat</string>
  <string name="chat_display_default">Messages will display here</string>
  <string name="chat_entry_default">Type your text here</string>
  <string name="send_button">Send</string>
  <string name="chat_entry_label">Enter Chat Text</string>
  <string name="greeting">Ciao</string>
</resources>

Now, in MainActivity.kt, update the layout as follows:

setContent {
  KodecoChatTheme {
    Surface(modifier = Modifier.fillMaxSize()) {
      Box(modifier = Modifier.fillMaxSize()) {
        Column(
          Modifier
            .fillMaxSize()
            .padding(50.dp)
        )
        {
          OutlinedTextField(
            value = "",
            onValueChange = {  },
            label = { Text("Label") }
          )
          Greeting(
            name = "Android"
          )
        }
      }
    }
  }
}

This adds an OutlinedTextField above the original text and changes the layout containers a bit. However, your text is still hard-coded. Build and run to make sure the app still builds. It should look like this now:

<img src="images/add_label.png" width="250" height="500">

Now you’ve got two labels, but all the text is still hard-coded.

Change the label value of the OutlinedTextField from:

label = { Text("Label") }

To:

label = { Text(text = stringResource(id = R.string.chat_entry_label)) }

Make sure to add your import for stringResource. Remember earlier when you learned about “R”, for “Resource”? Android has resource files that store certain assets, such as strings and images. Back in the legacy days, another resource would have been the XML layout files.

stringResource() is a Compose UI method that loads a string resource from a resource XML file. It takes a single parameter, id, which is the resource identifier. id is an integer, but you don’t need to know what the specific value is; instead, you can get Android to look it up for you by using that special “R” class. If you type in the code rather than copy-and-pasting it, after you type “R.string” and the “.” following it, Android Studio pulls up all the possible code completion options from the strings.xml file.

Delete everything inside the curly braces after “R”, then type “.” after the R.

Choose the first option, string, which references strings.xml. Then, type “.” and, again, Android Studio shows you all possible code completions, starting with a list of all the strings in strings.xml.

Choose chat_entry_label from the options to finish setting up the label.

Next, update the text displayed inside the original text:

@Composable
fun Greeting(name: String) {
  val greetingText = stringResource(id = R.string.greeting)
  Text(
    text = "$greetingText, $name!"
  )
}

Rerun the app if you don’t see it automatically update on your device or emulator. The strings for the text field and the outlined text field label are now retrieved from strings.xml, meaning they’re localized!

Adding Images

Next, you’ll see how to add some image assets to your app.

Copy/paste the following assets from /res/drawable in the final project to the same location in your project:

  • kodeco_logo.xml
  • kodeco_logo_back.xml

These are vector graphics.

In MainActivity.kt, add the following code right above the outlined text field:

Box() {
  Icon(
    painter = painterResource(id = R.drawable.kodeco_logo_back),
    contentDescription = null,
    tint = Color(0xFFFF5A00)
  )
  Icon(
    painter = painterResource(id = R.drawable.kodeco_logo),
    contentDescription = null,
    tint = Color.White
  )
}

Just like with string resources, for a drawable asset, you also use R to access it. Build and run. Voila! Now the Kodeco logo appears in your app.

<img src="images/add_vector_asset.png" width="250" height="500">

Next, open the Manifest file, AndroidManifest.xml. Command-click on macOS or Control-click on Windows/Linux this line:

android:roundIcon="@mipmap/ic_launcher_round"

To jump to the definition of the icon for the app.

Choose the first option, ic_launcher_round.xml.

For the foreground and background assets, replace the reference listed with the XML vector you added earlier:

<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
  <background android:drawable="@drawable/kodeco_logo" />
  <foreground android:drawable="@drawable/kodeco_logo_back" />
  <monochrome android:drawable="@drawable/kodeco_logo" />
</adaptive-icon>

Build and run. Now, the Kodeco logo is used for the app icon. This is an adaptive app icon, so if you’ve chosen to use themed icons on your Android device, the monochrome version is used to color match your chosen phone background art. When the app launches, you now see the Kodeco logo being used in the launch screen. And when you swipe up to see the open apps, you see the Kodeco logo there as well.

<img src="images/adaptive_icon.png" width="250" height="500" style="margin-right: 10px;">
<img src="images/app_icon2.png" width="250" height="500">
<img src="images/app_icon3.png" width="250" height="500">

Great job! You’ve customized the app icon and localized the app!

See forum comments
Cinema mode Download course materials from Github
Previous: Your First Android Project Next: Conclusion