DEV Community

Janire Fernandez
Janire Fernandez

Posted on

Shimmer Effect on Android

What is a Shimmer Effect?

Shimmer Effect Demo

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'
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
    }
}
Enter fullscreen mode Exit fullscreen mode

And that's all!!

If you want to check the whole project here you have the link: ShimmerEffectAndroid

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

Useful links:

Top comments (0)