Pull to Refresh – Part 2

In the previous article we started wiring up Chris Banes’ excellent Pull to Refresh library. We have got the “pull” part working, but it does not yet perform the “refresh” part of the process. In this article we’ll continue wiring things up, and also look at how we can customise things a little.

The first thing that we need to do is to connect up the PullToRefreshListView to trigger the refresh action that we defined previously, and update things once the refresh is complete. We’ll change our onCreate method:

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	mAdapter = new ArrayAdapter<String>(this,
		android.R.layout.simple_list_item_1, android.R.id.text1,
		Arrays.asList(sContent));
	PullToRefreshListView listView = (PullToRefreshListView) findViewById(android.R.id.list);
	listView.setAdapter(mAdapter);
	listView.setOnRefreshListener(new OnRefreshListener<ListView>() {

		@Override
		public void onRefresh(final PullToRefreshBase<ListView> lv) {
			mRefresh.setActionView(R.layout.layout_progress);
			mHandler.postDelayed(new Runnable() {

				@Override
				public void run() {
					refreshComplete();
					lv.onRefreshComplete();
				}
			}, 2000);
		}
	});
}

What we are doing is setting an OnRefreshListener which gets triggered when the user drags down and releases. We’ll update the legacy refresh control to show that a refresh is in progress, even though the PulltoRefreshListView will show the refreshing state. We’ll use the same simulated refreshing that we did before, which simply waits for 2 seconds before completing. On thing that we must do is to tell the PullToRefreshListView when the refresh is complete so that it can stop showing “refreshing’. This is done using the onRefreshingComplete() method. It is worth noting that because we are calling this from inside a Runnable we need to declare the argument to the onRefresh method of OnRefreshListener as final otherwise it won’t be accessible to an inner class.

If we run this, the pull down looks as it did at the end of the previous article, but we now show a refreshing state while the refresh is ongoing (which is also reflected in the “refresh’ button in the ActionBar:

There’s one small gotcha at this point. This all appears to work, but if you rotate the device you get an exception thrown. This is because originally we implemented this using ListActivity, and gave the ListView and id of @android:id/list in the layout. This now causes us some problams, so it is necessary to change the id to something within our domain, rather than using an android identifier, so we’ll use @+id/pulllist instad in the layout and change on line in onCreate:

PullToRefreshListView listView = (PullToRefreshListView) findViewById(R.id.pulllist);

Now that we have the basic Pull To Refresh functionality working, let’s have a look at how we can customise things. Chris has provided quite a few ways of customising how this control works. Most of these are done using some custom attributes in your layout xml, so we’ll look at one to demonstrate how to use them. The one that we’ll use allows us to show a subtle visual clue that Pull To Refresh is supported on this control:

To do this we have to set the ptrShowIndicator attribute on the control in the XML layout:

<com.handmark.pulltorefresh.library.PullToRefreshListView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ptr="http://schemas.android.com/apk/res-auto"
    android:id="@+id/pulllist"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" 
    ptr:ptrShowIndicator="true">

</com.handmark.pulltorefresh.library.PullToRefreshListView>

Setting the attribute is easy enough, but we must also declare the namespace in which this attribute resides. When declaring these attributes, Chris created them in res/values/attrs.xml file in his project. We have imported Chris’ project as an Android Library project which will effectively merge the resources from Chris’ project in to those in our project. To access attributes declared within our project, we need to specify the correct namespace, and we do this thus:

    xmlns:ptr="http://schemas.android.com/apk/res-auto"

We can then access these attributes by using the ptr prefix that we have just defined:

    ptr:ptrShowIndicator="true"

If we run that we can now see that the indicator appearing as in the earlier picture.

That concludes our look at Chris’ Pull To Refresh library. Chris deserves great credit for producing a library which has a clean, well-defined interface which makes it very quick and easy to add to a project, and even retrofitting it, as we have seen, is very easy because of this.

Finally, I should point out that there is plenty of discussion within the Android community about whether Pull To Refresh should be used in Android apps. Styling Android is about technical howto’s rather than exploring if you should. For those wishing to read those discussions, a good starting point is this post on Juhani Lehtimäki‘s excellent Android UI Patterns blog.

The source code for this article can be found here.

© 2012, Mark Allison. All rights reserved. This article originally appeared on Styling Android.

Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License

Send the author to the moon!

Creative Commons License
Pull to Refresh – Part 2 by Styling Android, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Terms and conditions beyond the scope of this license may be available at blog.stylingandroid.com.

Tags:

One Response to “Pull to Refresh – Part 2”

  1. Assh says:

    Thanks a lot sir, do you have a YouTube channel where you post video tuts like this??

Leave a Reply