SwipeRefreshLayout refresh animation doesn't stop

blavi picture blavi · May 28, 2015 · Viewed 35.2k times · Source

I've implemented a fragment which has a SwipeRefreshLayout as content view. Refresh animation is triggered at onRefresh but it never stops even if setRefreshing is set to false after retrieving the data from server.

    @Override
public void onRefresh() {
    handler.post(refreshing);
}


private final Runnable refreshing = new Runnable(){
    public void run(){
        try {
            if(isRefreshing()){
                handler.postDelayed(this, 1000);
            }else{
                swipeLayout.setRefreshing(false);
                mainActivity.forceUpdate();
                setLayout();
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
};

private boolean isRefreshing(){
    return swipeLayout.isRefreshing();
}

Answer

JozeRi picture JozeRi · May 28, 2015

well, of course it's not stopping to refresh, look at your loop.

if(isRefreshing()){
    handler.postDelayed(this, 1000);
}else{
    swipeLayout.setRefreshing(false);
    mainActivity.forceUpdate();
    setLayout();
}

basically you are never stopping it, the "swipeLayout.setRefreshing(false);" is never called, since the condition it needs is (isRefreshing()) to be false, so it doesn't make any sense, you will always get a true value from "isRefreshing()" since you're never telling it to stop. setRefreshing to false based on the boolean value of isRefreshing is wrong in my opinion, you shouldn't rely on it, you should be the one to decide when you want to stop the refresh state.

usually PullToRefresh is used to get new data from server. so basically I would recommend inserting this check right where you get an answer from your server :

if (swipeLayout.isRefreshing()) {
     swipeLayout.setRefreshing(false);
}

because once you get your new data from the server, that's when you need to stop refreshing.

EDIT - added a full code example

protected SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
    @Override
    public void onRefresh() {
        retrieveDocuments();
    }
};

public void retrieveDocuments() {
//some code, server call

//onCompletion is your server response with a success
@Override
public void onCompletion(String result) {

    if (mSwipeRefreshLayout.isRefreshing()) {
       mSwipeRefreshLayout.setRefreshing(false);
    }
}

}