LMaker
LMaker

Reputation: 1630

Android - Best way to use shimmer layout from Facebook

I'm using the Shimmer layout now in my new apps, and its really awesome.

I've started to use this library to handle the shimmer effect with RecyclerView.

But, I dont know how to do use this shimmer effect in a static layout, like a detail activity of a product for example.

I need to set all my TextView's background to gray and programmatically set to normal after a success request?

I really don't get it. Can you help me with this concept?

Upvotes: 3

Views: 10718

Answers (1)

Rene Ferrari
Rene Ferrari

Reputation: 4206

Ok I will just show you the code and explain it afterwards:

Layout file (only important part):

    <android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginTop="8dp"
    app:contentPadding="16dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!-- MOCK Layout (when you are still fetching data) -->
        <com.facebook.shimmer.ShimmerFrameLayout
            android:layout_width="match_parent"
            android:id="@+id/sflMockContent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="@id/llRealContent"
                android:orientation="vertical"
                android:visibility="visible">

                <View
                    android:layout_width="50dp"
                    android:layout_height="10dp"
                    android:background="#e9e9e9" />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="10dp"
                    android:layout_marginTop="16dp"
                    android:background="#e9e9e9" />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="10dp"
                    android:layout_marginTop="8dp"
                    android:background="#e9e9e9" />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="10dp"
                    android:layout_marginTop="8dp"
                    android:background="#e9e9e9" />
            </LinearLayout>
        </com.facebook.shimmer.ShimmerFrameLayout>

        <!-- Real Layout where you set the content then -->
        <LinearLayout
            android:id="@+id/llRealContent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:visibility="gone">

            <TextView
                android:id="@+id/tvProductName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <TextView
                android:id="@+id/tvProductDescription"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp" />
        </LinearLayout>
    </RelativeLayout>
</android.support.v7.widget.CardView>

Kotlin using kotlinx for view binding:

    sflMockContent.startShimmerAnimation()

    Handler().postDelayed( {
        tvProductName.setText("StackOverflow Answer")
        tvProductDescription.setText("Look at this awesome product. Produced by a programmer for helping out other programmers!")
        sflMockContent.visibility = View.GONE
        llRealContent.visibility = View.VISIBLE
    }, 10000)

Java version of the Code (without findViewById() part):

sflMockContent.startShimmerAnimation();

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        tvProductName.setText("StackOverflow Answer");
        tvProductDescription.setText("Look at this awesome product. Produced by a programmer for helping out other programmers!");
        sflMockContent.setVisibility(View.GONE);
        llRealContent.setVisibility(View.VISIBLE);
    }
}, 10000);

Okay first of all: You do not need the ShimmerRecyclerView Library for this use case. I have only used the ShimmerLayout (build.gradle):

    implementation 'com.facebook.shimmer:shimmer:0.1.0@aar'

My basic idea was to overlap the Mock Layout with the Content Layout. To my knowledge best practice is using a RelativeLayout rather than a FrameLayout for this. To overlap I have set android:layout_centerHorizontal="@id/llRealContent" in the Mock Layout (I'd advise you to set layout_centerVertical as well). The ShimmerFrameLayout should represent the Root-ViewGroup of this Mock Layout.

In your Mock Layout you just create your Mock Views (meaning the "grey stripes" signaling the user where to expect content). I have made a very simplistic example but of course it will work on more complex layouts. The mock layout should look as close as possible to the real one (I would advise to just copy & paste the real layout and change every TextView etc. to a View and set the background and size as needed).

It is important to set the visibility of the Root-ViewGroup of the Content Layout to gone so you won't see it and it won't take out any layout space.

In the Kotlin/Java code I - for the sake of simplicity - just set the TextView texts with a 10 second delay. As a first step you must activate the shimmer effect via sflMockContent.startShimmerAnimation().

Then fetch your content (from a REST-API, database, whatever). Once you have sucessfully fetched AND set all your data in your Content Layout you just have to set the visibility of the Mock Layout to Gone and the visibility of the Content Layout to Visible

Voilah!

(Note that the quality of this code is not great - for the sake of simplicity :D)

Upvotes: 4

Related Questions