Android swipe to refresh, only at the top of the list

Jun 10th, 2015 in Android by Michael Cho

← All articles


Build a swipe to refresh list, which only refreshes when at the top of the list.

One minor issue I had with using the standard Android ListView for a SwipeRefreshLayout was that it kept refreshing, even when the user was merely trying to scroll down the list (instead of pulling down to refresh). 

Here's how I overrode the onScroll method on the ListView, so that it only refreshed when the user is already at the very top of the list.

The layout file

Firstly, in your xml file make sure to use the SwipeRefreshLayout element. Here is my example from res/layout/main.xml:


<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_refresh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
    >

    <ListView
        android:id="@+id/listview_forecast"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@null"
        />

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

  

Override onScroll

Then in your activity file, ensure that you set an onscroll listener on this ListView element:


    // inside the activity class, perhaps in the onCreate method

    View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    mListView = (ListView) rootView.findViewById(R.id.listview_forecast);

    mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
      private boolean scrollEnabled;

      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
      }

      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        int topRowVerticalPosition =
            (mListView == null || mListView.getChildCount() == 0) ?
                0 : mListView.getChildAt(0).getTop();

        boolean newScrollEnabled =
            (firstVisibleItem == 0 && topRowVerticalPosition >= 0) ?
                true : false;

        if (null != mainActivity.mSwipeRefreshLayout && scrollEnabled != newScrollEnabled) {
          // Start refreshing....
          mainActivity.mSwipeRefreshLayout.setEnabled(newScrollEnabled);
          scrollEnabled = newScrollEnabled;
        }

      }
    });