ShimmerFrameLayout - An Alternative To ProgressBar In Android

Introduction

 
The shimmer is a library that provides the shimmer effect with the help of the ShimmerLayout class. It is developed by Facebook. The shimmer effect can be added to a single view or an entire layout.
 
Nowadays, progress bars in Android are not so attractive and do not make the app's layout great. Well, Shimmer solves this problem by providing a great animation of the shimmer effect. Modern applications mostly use the shimmer effect to show their lists.
 
In this article, we will develop an application that shows the loading of a list with the shimmer effect, not with a progress bar.
 
Step 1
 
Add Shimmer Gradle to your build.gradle. 
  1. apply plugin: 'com.android.application'  
  2.   
  3. android {  
  4.     compileSdkVersion 28  
  5.     defaultConfig {  
  6.         applicationId "yourdomain.shimmereffectsample"  
  7.         minSdkVersion 21  
  8.         targetSdkVersion 28  
  9.         versionCode 1  
  10.         versionName "1.0"  
  11.         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"  
  12.     }  
  13.     buildTypes {  
  14.         release {  
  15.             minifyEnabled false  
  16.             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'  
  17.         }  
  18.     }  
  19. }  
  20.   
  21. dependencies {  
  22.     implementation fileTree(dir: 'libs', include: ['*.jar'])  
  23.     implementation 'com.android.support:appcompat-v7:28.0.0'  
  24.     implementation 'com.android.support.constraint:constraint-layout:1.1.3'  
  25.     testImplementation 'junit:junit:4.12'  
  26.     androidTestImplementation 'com.android.support.test:runner:1.0.2'  
  27.     androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'  
  28.   
  29.     implementation 'com.facebook.shimmer:shimmer:0.4.0'  
  30.   
  31.     implementation 'com.android.support:recyclerview-v7:28.0.0'  
  32. }  
After adding shimmer and recyclerview to the build.gradle, now add recyclerview to activity_main.xml.
 
Step 2
 
Adding recyclerview and ShimmerLayout to activity_main.xml -
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     >  
  6.   
  7.     <com.facebook.shimmer.ShimmerFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  8.         android:id="@+id/shimmer_view_container"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_gravity="center"  
  12.         android:orientation="vertical"  
  13.         android:background="#ffffff">  
  14.   
  15.         <LinearLayout  
  16.             android:layout_width="match_parent"  
  17.             android:layout_height="wrap_content"  
  18.             android:orientation="vertical">  
  19.             <include layout="@layout/list_shimmer_layout" />  
  20.             <include layout="@layout/list_shimmer_layout" />  
  21.             <include layout="@layout/list_shimmer_layout" />  
  22.             <include layout="@layout/list_shimmer_layout" />  
  23.             <include layout="@layout/list_shimmer_layout" />  
  24.             <include layout="@layout/list_shimmer_layout" />  
  25.         </LinearLayout>  
  26.     </com.facebook.shimmer.ShimmerFrameLayout>
  27.     <android.support.v7.widget.RecyclerView  
  28.         android:id="@+id/recycler_view"  
  29.         android:layout_width="match_parent"  
  30.         android:layout_height="match_parent" />  
  31.   
  32.   
  33. </RelativeLayout>  
Now, we can see that inside the ShimmerFrameLayout tag, a layout named list_shimmer_layout is added. So, it's time to code this layout.
 
Step 3
 
Add Views to list_shimmer_layout.xml .
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:id="@+id/main_view"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="80dp"  
  5.     android:paddingLeft="10dp"  
  6.     android:paddingRight="10dp">  
  7.   
  8.     <ImageView  
  9.         android:id="@+id/user_image_View"  
  10.         android:layout_width="45dp"  
  11.         android:layout_height="45dp"  
  12.         android:layout_centerVertical="true"  
  13.         android:background="#dddddd"  
  14.         android:scaleType="center" />  
  15.   
  16.   
  17.     <RelativeLayout  
  18.         android:layout_width="match_parent"  
  19.         android:layout_height="wrap_content"  
  20.         android:layout_centerVertical="true"  
  21.         android:layout_toEndOf="@id/user_image_View"  
  22.         android:padding="10dp">  
  23.   
  24.         <TextView  
  25.             android:id="@+id/discount_text_view"  
  26.             android:layout_width="match_parent"  
  27.             android:layout_height="18dp"  
  28.             android:background="#dddddd" />  
  29.   
  30.         <TextView  
  31.   
  32.             android:id="@+id/categories_heading_text_view"  
  33.             android:layout_width="150dp"  
  34.             android:layout_height="16dp"  
  35.             android:layout_below="@id/discount_text_view"  
  36.             android:layout_marginTop="4dp"  
  37.             android:background="#dddddd"  
  38.             android:paddingRight="10dp" />  
  39.   
  40.         <TextView  
  41.             android:id="@+id/categories_details_text_view"  
  42.             android:layout_width="200dp"  
  43.             android:layout_height="16dp"  
  44.             android:layout_below="@id/categories_heading_text_view"  
  45.             android:layout_marginTop="5dp"  
  46.             android:background="#dddddd"  
  47.             android:ellipsize="end"  
  48.             android:maxLines="2"  
  49.   
  50.             />  
  51.     </RelativeLayout>  
  52.   
  53.   
  54. </RelativeLayout>  
Step 4
 
Since we are showing the data and Shimmer effect on a list, let's create a list item layout. 
 
Add Views to list_items.xml.
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:id="@+id/main_view"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="80dp"  
  6.     android:paddingLeft="10dp"  
  7.     android:paddingRight="10dp">  
  8.   
  9.     <ImageView  
  10.         android:id="@+id/user_image_View"  
  11.         android:layout_width="45dp"  
  12.         android:layout_height="45dp"  
  13.         android:layout_centerVertical="true"  
  14.         android:src="@drawable/ic_user" />  
  15.   
  16.   
  17.     <RelativeLayout  
  18.         android:layout_width="match_parent"  
  19.         android:layout_height="wrap_content"  
  20.         android:layout_centerVertical="true"  
  21.         android:layout_toEndOf="@id/user_image_View"  
  22.         android:padding="10dp">  
  23.   
  24.         <TextView  
  25.             android:id="@+id/user_name_textview"  
  26.             android:layout_width="match_parent"  
  27.             android:layout_height="wrap_content"  
  28.             tools:text="Gaurav Kumar"  
  29.             android:textSize="15sp"/>  
  30.   
  31.         <TextView  
  32.   
  33.             android:id="@+id/user_profession"  
  34.             android:layout_width="match_parent"  
  35.             android:layout_height="wrap_content"  
  36.             android:layout_below="@id/user_name_textview"  
  37.             android:layout_marginTop="2dp"  
  38.             tools:text="Software Engineer"  
  39.             android:textSize="13sp"/>  
  40.   
  41.         <TextView  
  42.             android:id="@+id/user_address"  
  43.             android:layout_width="match_parent"  
  44.             android:layout_height="wrap_content"  
  45.             android:layout_below="@id/user_profession"  
  46.             android:layout_marginTop="2dp"  
  47.             android:textSize="13sp"  
  48.             tools:text="Noida"  
  49.   
  50.             />  
  51.     </RelativeLayout>  
  52.   
  53.   
  54. </RelativeLayout>  
Step 4
 
Here, we need a pojo class named  UserDataModel.java.
  1. public class UserDataModel {  
  2.   
  3.     String name;  
  4.     String profession;  
  5.     String city;  
  6.   
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.   
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14.   
  15.     public String getProfession() {  
  16.         return profession;  
  17.     }  
  18.   
  19.     public void setProfession(String profession) {  
  20.         this.profession = profession;  
  21.     }  
  22.   
  23.     public String getCity() {  
  24.         return city;  
  25.     }  
  26.   
  27.     public void setCity(String city) {  
  28.         this.city = city;  
  29.     }  
  30.   
  31.   
  32. }  
Step 4 
 
We need an adapter to show the data in the list. Let's see the adapter's code mentioned below. We have named it UserAdapter.java.
  1. import android.support.annotation.NonNull;  
  2. import android.support.v7.widget.RecyclerView;  
  3. import android.view.LayoutInflater;  
  4. import android.view.View;  
  5. import android.view.ViewGroup;  
  6. import android.widget.TextView;  
  7.   
  8. import java.util.ArrayList;  
  9.   
  10. public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {  
  11.   
  12.     private ArrayList<UserDataModel> mlist;  
  13.   
  14.     public UserAdapter(ArrayList<UserDataModel> list) {  
  15.   
  16.         mlist = list;  
  17.   
  18.     }  
  19.   
  20.     @NonNull  
  21.     @Override  
  22.     public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {  
  23.         View itemView = LayoutInflater.from(parent.getContext())  
  24.                 .inflate(R.layout.list_items, parent, false);  
  25.   
  26.         return new ViewHolder(itemView);  
  27.     }  
  28.   
  29.     @Override  
  30.     public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {  
  31.   
  32.         viewHolder.nameTextView.setText(mlist.get(i).getName());  
  33.         viewHolder.professionTextView.setText(mlist.get(i).getProfession());  
  34.         viewHolder.cityTextView.setText(mlist.get(i).getCity());  
  35.   
  36.     }  
  37.   
  38.     @Override  
  39.     public int getItemCount() {  
  40.         return mlist.size();  
  41.     }  
  42.   
  43.     public class ViewHolder extends RecyclerView.ViewHolder {  
  44.   
  45.         TextView nameTextView;  
  46.         TextView professionTextView;  
  47.         TextView cityTextView;  
  48.   
  49.         public ViewHolder(View itemView) {  
  50.             super(itemView);  
  51.   
  52.             nameTextView = itemView.findViewById(R.id.user_name_textview);  
  53.             professionTextView = itemView.findViewById(R.id.user_profession);  
  54.             cityTextView = itemView.findViewById(R.id.user_address);  
  55.   
  56.         }  
  57.   
  58.   
  59.     }  
  60.   
  61. }  
Step 5
 
Now, bind all the Views in MainActivity.java and initialize these Views. Here comes the java activity.
  1. import android.os.Bundle;  
  2. import android.os.Handler;  
  3. import android.support.v7.app.AppCompatActivity;  
  4. import android.support.v7.widget.DefaultItemAnimator;  
  5. import android.support.v7.widget.LinearLayoutManager;  
  6. import android.support.v7.widget.RecyclerView;  
  7. import android.view.View;  
  8.   
  9. import com.facebook.shimmer.ShimmerFrameLayout;  
  10.   
  11. import java.util.ArrayList;  
  12.   
  13. public class MainActivity extends AppCompatActivity {  
  14.   
  15.   
  16.     ShimmerFrameLayout shimmerLayout;  
  17.     RecyclerView mRecyclerView;  
  18.     ArrayList<UserDataModel> mUserArrayList;  
  19.     UserAdapter mAdapter;  
  20.   
  21.   
  22.     @Override  
  23.     protected void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.activity_main);  
  26.   
  27.         shimmerLayout = findViewById(R.id.shimmer_view_container);  
  28.         mRecyclerView = findViewById(R.id.recycler_view);  
  29.   
  30.         mUserArrayList = new ArrayList<>();  
  31.   
  32.         showShimmer();  
  33.   
  34.         final Handler handler = new Handler();  
  35.         handler.postDelayed(new Runnable() {  
  36.             @Override  
  37.             public void run() {  
  38.                 populateList();  
  39.                 mAdapter = new UserAdapter(mUserArrayList);  
  40.                 RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());  
  41.                 mRecyclerView.setLayoutManager(mLayoutManager);  
  42.                 mRecyclerView.setItemAnimator(new DefaultItemAnimator());  
  43.                 mRecyclerView.setAdapter(mAdapter);  
  44.                 hideShimmer();  
  45.             }  
  46.         }, 3000);  
  47.   
  48.   
  49.         // we are delaying so that shimmer effect can be seen because here we are not making any API call.  
  50.     }  
  51.   
  52.     private void populateList() {  
  53.   
  54.         UserDataModel dataModel = new UserDataModel();  
  55.         dataModel.setName("Gaurav Kumar");  
  56.         dataModel.setProfession("Android Developer");  
  57.         dataModel.setCity("Noida");  
  58.         mUserArrayList.add(dataModel);  
  59.   
  60.         UserDataModel dataModel1 = new UserDataModel();  
  61.         dataModel1.setName("Ashish Tiwari");  
  62.         dataModel1.setProfession("Unity Game Developer");  
  63.         dataModel1.setCity("Delhi");  
  64.         mUserArrayList.add(dataModel1);  
  65.   
  66.         UserDataModel dataModel2 = new UserDataModel();  
  67.         dataModel2.setName("Pravesh Dubey");  
  68.         dataModel2.setProfession("Ios Developer");  
  69.         dataModel2.setCity("Pune");  
  70.         mUserArrayList.add(dataModel2);  
  71.   
  72.         UserDataModel dataModel3 = new UserDataModel();  
  73.         dataModel3.setName("Praveen Singh togadia");  
  74.         dataModel3.setProfession("Web Developer");  
  75.         dataModel3.setCity("Gurgaon");  
  76.         mUserArrayList.add(dataModel3);  
  77.   
  78.         UserDataModel dataModel4 = new UserDataModel();  
  79.         dataModel4.setName("Narendra singh");  
  80.         dataModel4.setProfession("Sql Developer");  
  81.         dataModel4.setCity("Banglore");  
  82.         mUserArrayList.add(dataModel4);  
  83.   
  84.   
  85.     }  
  86.   
  87.     private void hideShimmer() {  
  88.         shimmerLayout.stopShimmer();  
  89.         shimmerLayout.setVisibility(View.GONE);  
  90.     }  
  91.   
  92.     private void showShimmer() {  
  93.         shimmerLayout.startShimmer();  
  94.         shimmerLayout.setVisibility(View.VISIBLE);  
  95.     }  
  96. }  
See, this is so simple to implement. Here, we are delaying the setting of the adapter because we are not making any API call. So, the effect can't be seen without delaying the output. Let's look at the two methods - showShimmer() and hideShimmer(). These two methods are responsible for showing and hiding the shimmer effect respectively.
 
Output 
 
There are several images to show the effect, so please see carefully the stages and the difference in images.
 
 
This is the initial stage of the shimmer. Now, let us see other images to mark a difference.
 
 
See the right side is darker and the left side of Views is lighter in color. This indicates that shimmer effect travels left to right. See another image for a clear explanation.
 
 
Now, after that effect, the data will load as below.
 
 

Conclusion

 
In this article, we learned about the shimmer effect with the help of various images. We saw the stages of shimmer layout with an animated wave traveling from left to right. Finally, our data loaded and the shimmer effect got hidden and stopped. I hope this article was helpful to you.


Similar Articles