How to create Shimmer Loading Animation with Jetpack Compose
Bored of the circular progress loader? In this tutorial, let us learn how to implement the shimmer loading effect, which looks much better and can significantly improve the UX, when loading a bunch of items. All modern apps like YouTube, Netflix, Facebook use this effect.
Usage: Especially used when loading a list of items.
First create a ShimmerListItem() composable.
@Composable
fun ShimmerListItem(
isLoading: Boolean,
barCount: Int,
modifier: Modifier = Modifier,
contentAfterLoading: @Composable () -> Unit,
) {
if (isLoading) {
Row(modifier = modifier) {
Column {
for (i in 1..barCount) {
Box(
modifier = Modifier
.fillMaxWidth((1f / i))
.height(20.dp)
.clip(RoundedCornerShape(6.dp))
.shimmerEffect()
)
Spacer(modifier = Modifier.height(12.dp))
}
}
}
} else {
contentAfterLoading()
}
}
fun Modifier.shimmerEffect(): Modifier = composed {
val transition = rememberInfiniteTransition()
val offsetX by transition.animateFloat(
initialValue = 0f,
targetValue = 2000f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 1200, easing = FastOutSlowInEasing)
)
)
background(
brush = Brush.horizontalGradient(
colors = listOf(
Color.LightGray.copy(alpha = 0.8f),
Color.LightGray.copy(alpha = 0.6f),
Color.LightGray.copy(alpha = 0.8f)
),
startX = 0f,
endX = offsetX
)
)
}
Let's understand the parameters.
isLoading - Boolean which represents the state of the item. It will show the Shimmer effect when true, and the contentAfterLoading composable when false.
barCount - Represents the number of horizontal simmer effect bars in one ShimmerListItem.
modifier - Modifier to edit the size.
contentAfterLoading - Place the item to display after loading is over in here as a composable.
Now simply use it in for example in a LazyColumn() like:
LazyColumn {
items(itemCount) {
ShimmerListItem(isLoading = it.isLoading, barCount = 3) {
Row {...}
}
}
}
Preview (with 3 bars):
If you don't want this horizontal bar like shape, or if you want to have the simmer effect anywhere else, you can use it on any other composable (e.g. in a Box) using the Modifier.shimmerEffect() as a modifier. Enjoy!
Thanks for reading this article! Hope you liked it!
Subscribe to my newsletter
Read articles from Subhradeep Bera directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Subhradeep Bera
Subhradeep Bera
I am a engineering sophomore at Jadavpur University, Kolkata. I am an aspiring software engineer and interested in android development. I try to share some of my experience and android content through my blogs.