Setting up Swipe To Refresh

We begin implementing the Swipe to Refresh pattern with a brand new Android Studio project and the most recent version of the Android Support Library (your SDK manager should show an Android Support Library version of at least 21.0).

The first thing we need to do is add the support library to our application€’s build.gradle file.


compile ''

Gradle sync your project and open the layout file that was generated when we created our first Activity from the new project wizard, named res/layouts/activity_main.xml. We’re going to add a ListView and a SwipeRefreshLayout widget to the layout file. The ListView will display content we want to update using the Swipe to Refresh pattern, and the SwipeRefreshLayout widget will provide the basic functionality.



Notice that ListView is nested within the SwipeRefreshLayout. Any time we swipe the ListView beyond the edge of the SwipeRefreshLayout, the SwipeRefreshLayout widget will display a loading icon and trigger an onRefresh event. This event is a hook for adding our own on-demand data refresh behavior for the list.

Wiring up the Adapter

Now that we’ve got our layout file ready, let’s set up a simple data adapter. In real life, our adapter would likely be backed by a web service, remote API or database, but to keep things simple we’ll fake a web API response. Include the following XML snippet in your res/strings.xml file:




and set up an adapter to fake out new responses from the “cat names web API” for our experiment.


class MainActivity extends Activity {

ListView mListView;
SwipeRefreshLayout mSwipeRefreshLayout;
Adapter mAdapter;

public void onCreate(Bundle savedInstanceState) {
SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(;
mListView = findViewById(;
mListView.setAdapter(new ArrayAdapter(){
String[] fakeTweets = getResources().getStringArray(R.array.fake_tweets);
mAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, fakeTweets)

Defining our Data Refresh

Now that our adapter is set up, we can wire up the refresh triggered by swiping down. We’ll get an animated loading indicator already “for free”; we just need to define what happens to our ListView. We will do that by defining the SwipeRefreshLayout widget’s expected OnRefreshListener interface. We’ll also simulate getting new data back from the CatNames webservice (we’ll build a method called getNewCatNames() that will build an array of randomly shuffled fake responses from the cat names API).


public void onCreate(Bundle savedInstanceState) {
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
public void onRefresh() {

// fake a network operation's delayed response
// this is just for demonstration, not real code!
private void refreshContent(){
new Handler().postDelayed(new Runnable() {
public void run() {
mAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, getNewTweets());

// get new cat names.
// Normally this would be a call to a webservice using async task,
// or a database operation

private List getNewCatNames() {
List newCatNames = new ArrayList();
for (int i = 0; i < mCatNames.size(); i++) {
int randomCatNameIndex = new Random().nextInt(mCatNames.size() - 1);
return newCatNames;


Notice the last line in refreshContent() in the previous listing: setRefreshing(false);. This notifies the SwipeRefreshLayout widget instance that the work we wanted to do in onRefresh completed, and to stop displaying the loader animation.


Now try running your app. Try swiping the ListView down and verify that the SwipeRefreshLayout loading icon displays, is dismissed, and that new tweets are loaded into the ListView. Congratulations! You’ve implemented the Swipe to Refresh pattern in your app.