ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Follow publication

Coil: My Favorite Image Loading Library for Jetpack Compose

Stefano Natali
ProAndroidDev
Published in
5 min readSep 29, 2024

Why Choose Coil?

Getting Started with Coil in Jetpack Compose

implementation("io.coil-kt:coil-compose:2.7.0")
@Composable
fun CoilImageExample(imageUrl: String) {
AsyncImage(
model = imageUrl,
contentDescription = "Sample image"
)
}

Customizing Image Loading

AsyncImage(
model = imageUrl,
contentDescription = "Sample image",
placeholder = painterResource(R.drawable.placeholder),
error = painterResource(R.drawable.error),
onLoading = { /* Show loading spinner */ },
onError = { /* Handle error */ },
onSuccess = { /* Do something on success */ }
)
var backgroundColor by remember {
mutableStateOf(Color.White)
}

AsyncImage(
model = imageUrl,
contentDescription = null,
contentScale = ContentScale.Fit,
modifier = Modifier
.fillMaxSize()
.background(backgroundColor),
onSuccess = {
val bitmap = (it.result.drawable as BitmapDrawable).bitmap.copy(
Bitmap.Config.ARGB_8888, true
)
backgroundColor = ImageUtils.parseColorSwatch(
Palette.from(bitmap).generate().dominantSwatch
)
},
)
object ImageUtils {
fun parseColorSwatch(color: Palette.Swatch?): Color {
return if (color != null) {
val parsedColor = Integer.toHexString(color.rgb)
return Color(parseColor("#$parsedColor"))
} else {
Color.White
}
}
}
  implementation("androidx.palette:palette-ktx:1.0.0")

Advanced Coil Features in Jetpack Compose

Image Transformations

AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(imageUrl)
.transformations(CircleCropTransformation())
.build(),
contentDescription = "Circular cropped image"
)

ImageLoader for GIFs, SVGs and VideoFrames

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

val painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current)
.data("https://example.com/image.gif")
.build(),
imageLoader = ImageLoader.Builder(context)
.components {
if (SDK_INT >= 28) {
add(ImageDecoderDecoder.Factory())
} else {
add(GifDecoder.Factory())
}
}
.build()
)

Image(
painter = painter,
contentDescription = stringResource(R.string.description)
)
class MyApplication : Application(), ImageLoaderFactory {
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.crossfade(true)
.build()
}
}
Coil.setImageLoader(ImageLoader.Builder(this)
.crossfade(true)
.build()
)

Conclusion

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Responses (1)

Write a response