Loading Images with Coil in Android: XML and Jetpack Compose

Introduction
Loading images efficiently is a crucial aspect of Android development. While there are several libraries available, Coil (Coroutine Image Loader) stands out for its simplicity, performance, and native Kotlin support. In this post, we’ll explore how to use Coil to load images in both traditional XML layouts and the modern Jetpack Compose toolkit.
Why Coil?
Coil is lightweight, fast, and integrates seamlessly with Kotlin and Coroutines. It supports a wide range of image formats, including GIFs, and offers powerful features like caching, placeholders, and image transformations out of the box.
Adding Coil to Your Project
First, add the Coil dependency to your build.gradle
file:
//For XML App
implementation("io.coil-kt:coil:2.7.0")
//For Compose App
implementation("io.coil-kt:coil-compose:2.7.0")
Replace 2.7.0
with the latest version available.
Using Coil in XML
Let’s start with a traditional XML-based layout. Coil provides an extension function for ImageView
that makes image loading straightforward.
XML Layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="centerCrop"/>
</LinearLayout>
Kotlin Code:
import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import coil.load
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val imageView: ImageView = findViewById(R.id.imageView)
imageView.load("https://example.com/image.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
}
}
}
Using Coil in Jetpack Compose
In Jetpack Compose, Coil is even easier to use, thanks to the rememberImagePainter
provided by the Coil library.
Jetpack Compose:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import coil.compose.rememberImagePainter
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { CoilImageExample() }
}
}
@Composable
fun CoilImageExample() {
val painter =
rememberImagePainter("https://example.com/image.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
}
Image(
painter = painter,
contentDescription = null,
modifier = Modifier.size(200.dp).padding(16.dp),
contentScale = ContentScale.Crop
)
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
CoilImageExample()
}
Jetpack Compose with Async Image:
@Composable
fun CoilImageExample() {
AsyncImage(
model = "https://example.com/image.jpg",
contentDescription = null,
)
}
Key Features of Coil
Crossfade: Adds a smooth transition between placeholder and loaded image.
Placeholders: Displays a placeholder image while the actual image is loading.
Error Handling: Shows a fallback image if the loading fails.
Conclusion
Whether you’re working with traditional XML layouts or embracing Jetpack Compose, Coil is a powerful and easy-to-use library for loading images in Android apps. With just a few lines of code, you can handle image loading, caching, and error management seamlessly.
If you found this guide helpful, share it with your developer friends and team, and stay tuned for more tutorials!
Subscribe to my newsletter
Read articles from Mukesh Rajput directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Mukesh Rajput
Mukesh Rajput
Specializing in creating scalable and maintainable applications using MVVM and Clean Architecture principles. With expertise in Ktor, Retrofit, RxJava, View Binding, Data Binding, Hilt, Koin, Coroutines, Room, Realm, and Firebase, I am committed to delivering high-quality mobile solutions that provide seamless user experiences. I thrive on new challenges and am constantly seeking opportunities to innovate in the Android development space.