About Francesco Azzola

I'm a senior software engineer with more than 15 yrs old experience in JEE architecture. I'm SCEA certified (Sun Certified Enterprise Architect), SCWCD, SCJP. I'm an android enthusiast and i've worked for long time in the mobile development field.

Android SwipeRefreshLayout Tutorial

In this post, we will describe SwipeRefreshLayout component. This component should be used whenever the user can refresh the UI using swipe gesture. In a previous post, we talked about another method to refresh the UI that we called shake to refresh, where the user shakes his smartphone and using accelerometer sensor the app refresh the UI. We talked about a custom implementation of this refresh pattern in this post where we implemented some like it.

The SwipeRefreshLayout component is a standard implementation provided by the SDK and it is already used in some App provided by Android (i.e Gmail).

Introduction

This component accepts only one child: the one we want to refresh. It uses a listener mechanism to inform the listener that holds this component that a refresh event occurred, so in other word our Activity, for example, has to implement an interface to be notified. The Activity is responsible to handle the refresh event and refreshing the corresponding View. If the listener, once it receives the event, determines that the refresh process should take place and wants to show a “refresh animation”, it has to call setRefrshing(true), otherwise it can cancel the animation calling setRefreshing(false).

How to use SwipeRefreshLayout

Now we know how this component works, we will create a simple example to show how to use it. Let us suppose we want to generate a random number as the user uses a vertical swipe gesture:

android_swipetorefreshlayout[5]

Usually this component is the root component:

<android.support.v4.widget.SwipeRefreshLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:id="@+id/swipe">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Random number:"
                android:id="@+id/lbl"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/rndNum"
                android:layout_toRightOf="@id/lbl"/>


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/lbl"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="20dp"
                android:text="Swipe to Refresh"
                style="@android:style/TextAppearance.Medium"/>



        </RelativeLayout>
    </ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

As you can see from the layout above, SwipeRefreshLayout has only one child. Now we can code our Activity:

...    
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final SwipeRefreshLayout swipeView = (SwipeRefreshLayout) findViewById(R.id.swipe);
        final TextView rndNum = (TextView) findViewById(R.id.rndNum);
        swipeView.setColorScheme(android.R.color.holo_blue_dark, android.R.color.holo_blue_light, android.R.color.holo_green_light, android.R.color.holo_green_light);
        swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                swipeView.setRefreshing(true);
                Log.d("Swipe", "Refreshing Number");
                ( new Handler()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeView.setRefreshing(false);
                        double f = Math.random();
                        rndNum.setText(String.valueOf(f));
                    }
                }, 3000);
            }
        });
    }
....

As you can see everything in our example happens in onCreate method. At line 6 we get the reference to the SwipeRefreshLayout so that we can set the listener (line 10,11,12). In the listener we simply can setRefreshing(true) to enable to refreshing animation and then we generate our random number. At the end (we emulate a quite long process) we stop the animation.

SwipeRefreshLayout with ListView

Another interesting example is how to use SwipeRefreshLayout with a ListView. This is an interesting example because in real app we have often this situation where we have a ListView holding some items and we want to refresh them. If the ListView is the only one child of the SwipeRefreshLayout we wouldn’t have any kind of problems, because everything works smoothly. In some cases we have not only the ListView but we have other elements, let us suppose we have an UI like this:

android_swipetorefreshlayout_listview[4]

This case is a little bit more complex, because if we scroll up the items in the ListView everything works as expected, but if the scroll down the refresh process starts and the list items doesn’t scroll as we want. In this case we can use a trick, we can disable the refresh notification using setEnabled(false) and enable it again as soon as the first item in the ListView is visible:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final SwipeRefreshLayout swipeView = (SwipeRefreshLayout) findViewById(R.id.swipe);

    swipeView.setEnabled(false);
    ListView lView = (ListView) findViewById(R.id.list);
    ArrayAdapter<String> adp = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, createItems(40,0 ));
    lView.setAdapter(adp);

    swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            swipeView.setRefreshing(true);
            ( new Handler()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    swipeView.setRefreshing(false);

                }
            }, 3000);
        }
    });

    lView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {

        }

        @Override
        public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (firstVisibleItem == 0)
                    swipeView.setEnabled(true);
                else
                    swipeView.setEnabled(false);
        }
    });
}

As you can see at line 33, we override the onScrollListener of the ListView to handle the enable/disable mechanism.

Reference: Android SwipeRefreshLayout Tutorial from our JCG partner Francesco Azzola at the Surviving w/ Android blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

One Response to "Android SwipeRefreshLayout Tutorial"

  1. Tim says:

    Instead of overriding the onScrollListener and handling disabling and enabling the swipeView inside of the onScroll method, you should be extending SwipeRefreshLayout in your View class and overriding canChildScrollUp().

Leave a Reply


+ 4 = ten



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close