What you'll learn
Apps aren't just text. This module covers showing images and icons, and Android's resources system — the proper home for your images, strings, and colours. You'll also learn the accessibility habit every image needs.
By the end you'll be able to:
- Use the resources folder and the
Rclass - Display images with
ImageandpainterResource - Add Material
Icons - Write good
contentDescriptions for accessibility
The resources system
Android keeps non-code assets in the res/ folder, and generates an R class so you can reference them safely in Kotlin. Instead of hard-coding a photo path or a piece of text, you point at a resource — which makes translation, theming, and different screen densities possible:
| Resource | Lives in | Referenced as |
|---|---|---|
Images / drawables | res/drawable/ | R.drawable.profile |
Strings | res/values/strings.xml | R.string.app_name |
Colors | res/values/colors.xml | R.color.brand |
Launcher icon | res/mipmap/ | the app icon |
Tip
strings.xml and read it with stringResource(R.string.x), rather than hard-coding it in your composables. It's the difference between an app you can translate into other languages later and one you can't.Images
The Image composable shows a picture; painterResource loads one from your drawables. Two touches make images look right: contentScale decides how the image fills its box (Crop fills and crops, Fit shows it whole), and Modifier.clip(CircleShape) makes the classic round avatar:
Image(
painter = painterResource(R.drawable.profile),
contentDescription = "Ada's profile photo",
contentScale = ContentScale.Crop, // fill the box, cropping overflow
modifier = Modifier
.size(96.dp)
.clip(CircleShape), // round avatar
)Note
AsyncImage — you'll meet it once you start networking in Phase 4. For now, painterResource covers images bundled in your app.Icons
Material Design ships a large set of icons available as Icons.Default.* (and other styles). The Icon composable draws them and a tint colours them. Icons are vectors, so they stay crisp at any size:
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = "Like",
tint = Color.Red,
)
// Pull user-facing text from resources, not hard-coded strings:
Text(text = stringResource(R.string.app_name))contentDescription
Both Image and Icon require a contentDescription — a text description read aloud by TalkBack, Android's screen reader. Describe the image's meaning ("Ada's profile photo"), not the word "image." If a graphic is purely decorative and adds no information, pass null so the screen reader skips it.
Key idea
contentDescription is the difference between an app a blind user can navigate and one they can't — and Compose makes you supply it, so take the moment to write a good one (or null when it's truly decorative).Recap & quick check
Key takeaways
- Non-code assets live in res/; the generated R class references them (R.drawable.x, R.string.x).
- Put user-facing text in strings.xml and read it with stringResource — it enables translation.
- Image + painterResource shows a bundled picture; contentScale and clip control fit and shape.
- Material Icons are available as Icons.Default.*; Icon draws them and tint colours them.
- Image/Icon require a contentDescription for screen readers — describe meaning, or null if decorative.
Quick check
1. How do you reference a bundled image named profile.png in code?
2. Why put text in strings.xml instead of hard-coding it?
3. Which contentScale fills the box and crops the overflow?
4. What is contentDescription for?
5. How do you make a square image into a round avatar?
Your UIs can look rich now — but they're still static. In the final module of Phase 1 we make them interactive with state.