Open In App

Shimmer Animation in Android using Jetpack Compose

Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisites:

Shimmer Animation was created by Facebook to show the loading screen while images are fetched from the server. Now we see shimmer animation in lots of places. In this article, we will take a look at the implementation of shimmer animation using the all-new Jetpack Compose. A sample GIF is given below to get an idea about what we are going to do in this article.

Shimmer Animation in Android using Jetpack Compose Sample GIF

Step by Step Implementation

Step 1:Create a New Project (Or use it in the existing Compose project)

To create a new project in the Android Studio Canary version, refer to the article How to Create a new Project in the Android Studio Canary Version with Jetpack Compose.

Step 2: Add Colors

Before moving to coding animation, add colors that shimmer animation will require. Open Colors.kt (Present in ui/theme/Colors.kt)

val ShimmerColorShades = listOf(

                                     Color.LightGray.copy(0.9f),

                                     Color.LightGray.copy(0.2f),

                                    Color.LightGray.copy(0.9f)

                                    )

It’s a list of background colors of compostable which is going to be animated, notice the color at index 1, this part will change its location, giving the shimmer effect.

Step 3: Working with the MainActivity.kt file

Create a composable function on which the animation will take place

Kotlin




@Composable
fun ShimmerItem(
    brush: Brush
) {
   // Column composable containing spacer shaped like a rectangle,
   // set the [background]'s [brush] with the brush receiving from [ShimmerAnimation]
   // Composable which is the Animation you are gonna create.
   Column(modifier = Modifier.padding(16.dp)) {
        Spacer(
            modifier = Modifier
                .fillMaxWidth()
                .size(250.dp)
                .background(brush = brush)
        )
        Spacer(
            modifier = Modifier
                .fillMaxWidth()
                .height(30.dp)
                .padding(vertical = 8.dp)
                .background(brush = brush)
        )
    }
}


Let’s create the animation. Create a new composable function.

Kotlin




@Composable
fun ShimmerAnimation(
) {
 
    /*
     Create InfiniteTransition
     which holds child animation like [Transition]
     animations start running as soon as they enter
     the composition and do not stop unless they are removed
    */
    val transition = rememberInfiniteTransition()
    val translateAnim by transition.animateFloat(
        /*
         Specify animation positions,
         initial Values 0F means it
         starts from 0 position
        */
        initialValue = 0f,
        targetValue = 1000f,
        animationSpec = infiniteRepeatable(
 
             
            // Tween Animates between values over specified [durationMillis]
            tween(durationMillis = 1200, easing = FastOutSlowInEasing),
            RepeatMode.Reverse
        )
    )
 
    /*
      Create a gradient using the list of colors
      Use Linear Gradient for animating in any direction according to requirement
      start=specifies the position to start with in cartesian like system Offset(10f,10f) means x(10,0) , y(0,10)
      end = Animate the end position to give the shimmer effect using the transition created above
    */
    val brush = Brush.linearGradient(
        colors = ShimmerColorShades,
        start = Offset(10f, 10f),
        end = Offset(translateAnim, translateAnim)
    )
 
    ShimmerItem(brush = brush)
}


Call the ShimmerItem which is going to animate, and pass the Brush object,

Step 4: Lay down the animated ShimmerItem onto the screen

In class MainActivity

Kotlin




class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ShimmerAnimationTheme(darkTheme = false) {
                Surface(color = MaterialTheme.colors.background) {
 
                    /*
                      Lazy column as I am adding multiple items for display purpose
                      create you UI according to requirement
                    */
                    LazyColumn {
 
                        /*
                          Lay down the Shimmer Animated item 5 time
                          [repeat] is like a loop which executes the body
                          according to the number specified
                        */
                        repeat(5) {
                            item {
                                ShimmerAnimation()
                            }
                        }
                    }
                }
            }
        }
    }
}


And we are done. This is the final code for MainActivity.kt file.

Kotlin




import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.*
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.shimmeranimation.ui.theme.ShimmerAnimationTheme
import com.example.shimmeranimation.ui.theme.ShimmerColorShades
 
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ShimmerAnimationTheme(darkTheme = false) {
                Surface(color = MaterialTheme.colors.background) {
 
                    /*
                      Lazy column as I am adding multiple items for display purpose
                      create you UI according to requirement
                     */
                    LazyColumn {
 
                        /**
                          Lay down the Shimmer Animated item 5 time
                          [repeat] is like a loop which executes the body
                          according to the number specified
                         */
                        repeat(5) {
                            item {
                                ShimmerAnimation()
 
                            }
                        }
                    }
                }
            }
        }
    }
}
 
@Composable
fun ShimmerAnimation(
) {
 
    /*
    Create InfiniteTransition
    which holds child animation like [Transition]
    animations start running as soon as they enter
    the composition and do not stop unless they are removed
    */
    val transition = rememberInfiniteTransition()
    val translateAnim by transition.animateFloat(
        /*
        Specify animation positions,
        initial Values 0F means it starts from 0 position
        */
        initialValue = 0f,
        targetValue = 1000f,
        animationSpec = infiniteRepeatable(
 
            /*
             Tween Animates between values over specified [durationMillis]
            */
            tween(durationMillis = 1200, easing = FastOutSlowInEasing),
            RepeatMode.Reverse
        )
    )
 
    /*
      Create a gradient using the list of colors
      Use Linear Gradient for animating in any direction according to requirement
      start=specifies the position to start with in cartesian like system Offset(10f,10f) means x(10,0) , y(0,10)
      end= Animate the end position to give the shimmer effect using the transition created above
    */
    val brush = Brush.linearGradient(
        colors = ShimmerColorShades,
        start = Offset(10f, 10f),
        end = Offset(translateAnim, translateAnim)
    )
 
    ShimmerItem(brush = brush)
 
}
 
 
@Composable
fun ShimmerItem(
    brush: Brush
) {
 
    /*
      Column composable shaped like a rectangle,
      set the [background]'s [brush] with the
      brush receiving from [ShimmerAnimation]
      which will get animated.
      Add few more Composable to test
    */
    Column(modifier = Modifier.padding(16.dp)) {
        Spacer(
            modifier = Modifier
                .fillMaxWidth()
                .size(250.dp)
                .background(brush = brush)
        )
        Spacer(
            modifier = Modifier
                .fillMaxWidth()
                .height(30.dp)
                .padding(vertical = 8.dp)
                .background(brush = brush)
        )
    }
}


Output:

Get the complete project.



Last Updated : 15 Dec, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads