Shimmer Animation for Android developers
You might have noticed the shimmer effect on Facebook’s mobile app while the data is loading from the network. Shimmer library was created by Facebook to display an animation when data is loading to make the UI more interesting and beautiful,
instead of using the traditional ProgressBar. Facebook, later on, released an open-source library called Shimmer which we can use it to implement the Shimmer Effect Placeholder.
Shimmer for Android is implemented as a layout, which means that you can simply nest any view inside a ShimmerFrameLayout.
The following is an example of Shimmer effect in an Android application:
In this blog, we will demonstrate how to use Shimmer in your Android application. We will build the shimmer layout design and start and stop the animation when data being load and loaded.
Knowledge required to use this animation
- Basic Android knowledge with java/kotlin and xml for design layouts
- Recycler view
Add dependencies
Add the following dependencies in your app level build.gradle and sync.
1 |
implementation 'com.facebook.shimmer:shimmer:0.1.0@aar' |
Now, Add item_layout.xml in the layout folder and add the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="60dp"> <ImageView android:id="@+id/imageViewAvatar" android:layout_width="60dp" android:layout_height="0dp" android:padding="4dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/textViewUserName" style="@style/TextAppearance.AppCompat.Large" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="4dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/imageViewAvatar" app:layout_constraintTop_toTopOf="parent" tools:text="Mobikul" /> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/textViewUserEmail" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@+id/textViewUserName" app:layout_constraintTop_toBottomOf="@+id/textViewUserName" tools:text="Mobikul" /> </androidx.constraintlayout.widget.ConstraintLayout> |
Now, Add shimmer_placeholder_layout.xml in the layout folder and add the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="60dp"> <ImageView android:id="@+id/imageViewAvatar" android:layout_width="60dp" android:layout_height="0dp" android:background="@color/colorGrey" android:padding="4dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/textViewUserName" style="@style/TextAppearance.AppCompat.Large" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="4dp" android:background="@color/colorGrey" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/imageViewAvatar" app:layout_constraintTop_toTopOf="parent" tools:text="Mobikul" /> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/textViewUserEmail" android:layout_width="0dp" android:layout_height="wrap_content" android:background="@color/colorGrey" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@+id/textViewUserName" app:layout_constraintTop_toBottomOf="@+id/textViewUserName" tools:text="Mobikul" /> </androidx.constraintlayout.widget.ConstraintLayout> |
Above in the XML,
Note– an important thing to note is that the background color should be grey or any non-white color since the shimmering effect won’t be visible if the background is white.
Do not forget to add the color in the colors.xml like below:
1 |
<color name="colorGrey">#dddddd</color> |
Now, Open the activity_main.xml file and add the below code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.facebook.shimmer.ShimmerFrameLayout android:id="@+id/shimmerFrameLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:orientation="vertical"> <!-- Adding 15 rows of placeholders --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> <include layout="@layout/shimmer_placeholder_layout" /> </LinearLayout> </com.facebook.shimmer.ShimmerFrameLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" /> </androidx.constraintlayout.widget.ConstraintLayout> |
Understanding the above code:
- We have added the ShimmerFrameLayout.
- Next, inside the ShimmerFrameLayout, we need to include some placeholder layouts(shimmer_placeholder_layout) inside LinearLayout.
- These are blank layouts similar to our RecyclerView layouts on which the shimmering effect will be performed while the network call is going on.
Note that we have added these placeholder layouts multiple times to create the appearance as a list. - The RecyclerView will display the list of data fetched after executing network requests and receiving the content from the API.
We have setup shimmer layout animation in design, Now its time to start and stop animation from Java class.
Get a ShimmerFrameLayout instance like below from id write down in MainActivity.java
1 2 |
ShimmerFrameLayout shimmerFrameLayout = findViewById(R.id.shimmerFrameLayout); RecyclerView recyclerView = findViewById(R.id.recyclerView); |
When you want to start the Animation –
1 2 3 |
recyclerView.setVisibility(View.GONE); shimmerFrameLayout.setVisibility(View.VISIBLE); shimmerFrameLayout.startShimmerAnimation(); |
When you want to stop shimmer animation and show recycler view data.
1 2 3 |
recyclerView.setVisibility(View.VISIBLE); shimmerFrameLayout.stopShimmerAnimation(); shimmerFrameLayout.setVisibility(View.GONE); |
Start the animation when you request the data from the server or local database and stop when you get the data from the source. Your result will look like