Shimmer Effect on Android
Tags: shimmer, android, kotlin, github
Published: 2022-08-10 15:06:00

## What is a Shimmer Effect?

![Shimmer Effect Demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/549b151ppif3zee6xywz.gif)
 

Its an effect to show a loading status. Instead of using a progress, Shimmer effect creates a better design for ux. It mimics the page’s layout by showing its elements in a shape similar to the actual content as it is loading and becoming available (i.e. when network latency allows).

## How to implement this on Android?

There is is an Android library, Shimmer, that provides an easy way to add a shimmer effect to any view in your Android app. 

So lets start!

First include the library dependency:

```
dependencies {
    // Shimmer
    implementation 'com.facebook.shimmer:shimmer:0.5.0'
}
```

Now create a layout `list_placeholder_layout.xml` that will act as a placeholder while content is loading. 

In my example I have an imageView to display the image of the animal and two textViews for the name and the type. So the layout is something like this:

```
<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginStart="10dp">

    <androidx.cardview.widget.CardView
        android:id="@+id/animal_image"
        android:layout_width="120dp"
        android:layout_height="150dp"
        android:backgroundTint="@color/gray"
        app:cardCornerRadius="20dp"
        app:cardElevation="4dp"
        app:cardUseCompatPadding="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.cardview.widget.CardView
        android:id="@+id/animal_name"
        android:layout_width="120dp"
        android:layout_height="30dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="30dp"
        android:backgroundTint="@color/gray"
        app:cardCornerRadius="10dp"
        app:cardElevation="4dp"
        app:cardUseCompatPadding="true"
        app:layout_constraintStart_toEndOf="@id/animal_image"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.cardview.widget.CardView
        android:id="@+id/animal_type"
        android:layout_width="120dp"
        android:layout_height="30dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:backgroundTint="@color/gray"
        app:cardCornerRadius="10dp"
        app:cardElevation="4dp"
        app:cardUseCompatPadding="true"
        app:layout_constraintStart_toEndOf="@id/animal_image"
        app:layout_constraintTop_toBottomOf="@id/animal_name" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

Once the layout is created we need to include it in the main layout `activity_main`, where the recyclerView is situated. 

To do that, we include `<com.facebook.shimmer.ShimmerFrameLayout>`

```
<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.main.MainActivity">

    <com.facebook.shimmer.ShimmerFrameLayout
        android:id="@+id/shimmer_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        tools:duration="800">

        <!-- Adding 8 rows of placeholders -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <include layout="@layout/list_placeholder_layout" />
            <include layout="@layout/list_placeholder_layout" />
            <include layout="@layout/list_placeholder_layout" />
            <include layout="@layout/list_placeholder_layout" />
            <include layout="@layout/list_placeholder_layout" />
            <include layout="@layout/list_placeholder_layout" />
            <include layout="@layout/list_placeholder_layout" />
            <include layout="@layout/list_placeholder_layout" />
        </LinearLayout>

    </com.facebook.shimmer.ShimmerFrameLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginStart="5dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

In the next step, we just need to tell Shimmer when to start and stop the animation. 

- We should start the Shimmer when we fetch the list of items.
`binding.shimmerView.startShimmer()` 
- We should stop the Shimmer when we get the list of items. 
`binding.shimmerView.stopShimmer()`

Also, we should hide the visibility of the Shimmer Frame Layout, when we have the list of items. 
`binding.shimmerView.isVisible = false`

```
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    private val viewModel: MainViewModel by viewModels()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //Start Shimmer
        binding.shimmerView.startShimmer()

        viewModel.getAnimals(10)
        viewModel.animalList.observe(this) {
            initRecyclerView(it)
        }
    }

    private fun initRecyclerView(animalList: List<Animal>) {
        
        binding.recyclerView.layoutManager = LinearLayoutManager(this)
        val adapter = AnimalAdapter(animalList)
        binding.recyclerView.adapter = adapter
        //Stop Shimmer
        binding.shimmerView.stopShimmer()
        //Hide Shimmer view
        binding.shimmerView.isVisible = false
    }
}
```

And that's all!! 

If you want to check the whole project here you have the link: [ShimmerEffectAndroid](https://github.com/janirefdez/ShimmerEffectAndroid)

Don't forget to like and share! Thank you! :) 


Useful links: 
- https://facebook.github.io/shimmer-android/