Android Beginners

Lesson 25: Images and Media: Loading Images with Coil

Ahmad Najar Ahmad Najar 1 min read

Images and Media: Loading Images with Coil

Back in lesson 10, we noted Compose's core library can't load images from a URL. Coil is the standard library that fills that gap.

Add the dependency

implementation("io.coil-kt:coil-compose:2.7.0")

Loading an image from a URL

AsyncImage(
    model = "https://picsum.photos/200",
    contentDescription = "A random photo",
    modifier = Modifier.size(120.dp)
)

That's genuinely the whole basic API — AsyncImage handles downloading, decoding, memory caching, and disk caching automatically. Compare this to lesson 25's worth of manual work this would have taken in the old View system.

Placeholder and error states

AsyncImage(
    model = imageUrl,
    contentDescription = "Task attachment",
    placeholder = painterResource(R.drawable.placeholder),
    error = painterResource(R.drawable.error_image),
    modifier = Modifier.size(120.dp)
)

Always set both — a placeholder shows while the image is loading, and the error image shows if the URL is broken or there's no connection. Skipping these means users see a blank box, which reads as broken even when it's just still loading.

Sizing images correctly

AsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data(imageUrl)
        .size(300) // request a reasonably sized image, not the full original
        .build(),
    contentDescription = "Task attachment",
    contentScale = ContentScale.Crop
)

Requesting an appropriately sized image (rather than a full-resolution photo for a 120dp thumbnail) noticeably improves loading speed and memory usage — a real, common performance issue in apps that skip this.

Next: Lesson 26 — running work in the background, even when your app isn't open, with WorkManager.

Android Beginners