We usually use spinner loaders when the application wants to load data from network calls. Instead of using ordinary loaders, we can make the loading screen more attractive using Facebook's Shimmer library. This library adds the Shimmer effect to whatever custom display we set. You can see this shimmer effect on Facebook's mobile and desktop applications.
This article describes how to use the Shimmer library in your application by example loading list data from JSON http calls.
1. Facebook Shimmer Library
To get the shimmer effect on any layout, you have to place your layout in ShimmerFrameLayout. To start animation, you must call startShimmerAnimation () in ShimmerFrameLayout. That's all, you can immediately see the shimmer effect on your layout. You can find additional documentation on the Shimmer page.
Below is the code snippet to get the Shimmer effect. First, place your layout inside ShimmerFrameLayout.
android:id=“@+id/shimmer_view_container”
android:layout_width=“wrap_content”
android:layout_height="wrap_content"
shimmer:duration="1000">
android:layout_width="100dp"
android:layout_height="8dp"
android:background="#dddddd" />
To start the animation, call startShimmerAnimation() from your activity.
ShimmerFrameLayout shimmerContainer = (ShimmerFrameLayout) findViewById(R.id.shimmer_view_container);
shimmerContainer.startShimmerAnimation();
2. Sample JSON
To demonstrate this example, I have created a sample JSON that contains a list of recipes. This endpoint simulates the network delay by adding 2 sec delay before responding the JSON so that the Shimmer effect can be noticed.
[{
"id": 1,
"name": "Salmon Teriyaki",
"description": "Put the ginger and garlic into a bowl and mix with the soy sauce, maple syrup, mirin and a drizzle of olive oil",
"price": 140,
"chef": "Gordon Ramsay",
"thumbnail": "https://api.androidhive.info/images/food/1.jpg",
"timestamp": "2 min ago"
}, {
"id": 2,
"name": "Grilled Mushroom",
"description": "Combine butter, dill and garlic salt, brush over mushrooms.",
"price": 150,
"chef": "Ravi Tamada",
"thumbnail": "https://api.androidhive.info/images/food/2.jpg",
"timestamp": "5 min ago"
}
]
Let’s try the Shimmer library by creating a simple app.
3. Creating New Project
1. Create a new project in Android Studio from File ⇒ New Project and select Basic Activity from templates.
2. Add Shimmer dependency to your build.gradle and rebuild the project.
build.gradle
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
// Shimmer
implementation 'com.facebook.shimmer:shimmer:0.1.0@aar'
}
3. Add the below colors and dimens to respective files.
colors.xml
dimens.xml
4. Create a new xml layout file called recipe_placeholder_item.xml. In this file we define the placeholder layout using plain display elements. All views will be placed similar to the actual item list.
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/activity_padding">
android:id="@+id/thumbnail"
android:layout_width="@dimen/placeholder_image"
android:layout_height="@dimen/placeholder_image"
android:layout_marginRight="@dimen/activity_padding"
android:background="@color/placeholder_bg" />
android:id="@+id/name"
android:layout_width="150dp"
android:layout_height="10dp"
android:layout_marginBottom="10dp"
android:layout_toRightOf="@id/thumbnail"
android:background="@color/placeholder_bg" />
android:layout_width="100dp"
android:layout_height="@dimen/placeholder_text_height"
android:layout_below="@id/name"
android:layout_toRightOf="@id/thumbnail"
android:background="@color/placeholder_bg" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/thumbnail"
android:layout_marginBottom="40dp"
android:layout_marginTop="20dp"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="@dimen/placeholder_text_height"
android:layout_marginRight="100dp"
android:background="@color/placeholder_bg" />
android:layout_width="match_parent"
android:layout_height="@dimen/placeholder_text_height"
android:layout_marginRight="50dp"
android:layout_marginTop="10dp"
android:background="@color/placeholder_bg" />
android:layout_width="match_parent"
android:layout_height="@dimen/placeholder_text_height"
android:layout_marginRight="160dp"
android:layout_marginTop="10dp"
android:background="@color/placeholder_bg" />
5. Because the placeholder view is ready, let's add to our main activity layout. Open your main activity layout file, activity_main.xml and include placeholder layout. We include placeholder layout three times to make it appear as a list.
activity_main.xml
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:shimmer="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
tools:context="info.androidhive.shimmer.MainActivity">
android:id="@+id/shimmer_view_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
shimmer:duration="800">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
6. Open MainActivity.java and start the Shimmer animation by calling the startShimmerAnimation () method on onResume (). We also stop animation on onPause () when the activity is paused.
MainActivity.java
import com.facebook.shimmer.ShimmerFrameLayout;
public class MainActivity extends AppCompatActivity {
private ShimmerFrameLayout mShimmerViewContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mShimmerViewContainer = findViewById(R.id.shimmer_view_container);
}
@Override
public void onResume() {
super.onResume();
mShimmerViewContainer.startShimmerAnimation();
}
@Override
public void onPause() {
mShimmerViewContainer.stopShimmerAnimation();
super.onPause();
}
}
3.1 Loading feed from JSON and hiding the Shimmer
Now when our Shimmer trimmer is ready, let's look at how to load the JSON feed in the RecyclerView and hide the loader shimmer after the list is created. By following the remaining articles, you will understand how to apply the Shimmer effect in real-world applications.
7. Open build.gradle and add dependencies to RecyclerView, Glide and Volley.
build.gradle
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
// ...
// Shimmer
implementation 'com.facebook.shimmer:shimmer:0.1.0@aar'
// RecyclerView
implementation 'com.android.support:recyclerview-v7:26.1.0'
// glide image library
implementation 'com.github.bumptech.glide:glide:3.7.0'
// volley http library
implementation 'com.android.volley:volley:1.0.0'
implementation 'com.google.code.gson:gson:2.6.2'
}
8. Create a class named MyApplication.java and extend the class from Application. This is a singleton class in which the Volley library will be initiated.
MyApplication.java
package info.androidhive.shimmer;
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class MyApplication extends Application {
public static final String TAG = MyApplication.class
.getSimpleName();
private RequestQueue mRequestQueue;
private static MyApplication mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized MyApplication getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public void addToRequestQueue(Request req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public void addToRequestQueue(Request req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
9. Open AndroidManifest.xml and add the MyApplication class to tag. We also need INTERNET permission as we are going to make http calls.
AndroidManifest.xml
package="info.androidhive.shimmer">
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".MyApplication"
android:theme="@style/AppTheme">
10. Open activity_main.xml and add RecyclerView widget below the ShimmerFrameLayout.
activity_main.xml
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:shimmer="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
tools:context="info.androidhive.shimmer.MainActivity">
android:id="@+id/shimmer_view_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
shimmer:duration="800">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />