Reputation: 1630
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
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