Skip to content

Instantly share code, notes, and snippets.

@Frikish
Last active February 23, 2017 08:57
Show Gist options
  • Save Frikish/10025057 to your computer and use it in GitHub Desktop.
Save Frikish/10025057 to your computer and use it in GitHub Desktop.
SwipeRefreshLayout with StickyListHeaders
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true">
<se.emilsjolander.stickylistheaders.StickyListHeadersListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>

Trying to find a solution

I had a problem getting the new fancy SwipeRefreshLayout from the appcompat lib to work with a custom listview, in this case the StickyListHeaders. Since the First child of the SwipeRefreshLayout should be either a ScrollView or a pure List, some workaround had to be done.

Hope this helps.

package com.test.application;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import com.test.application.R;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
public class ThatListFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private StickyListHeadersListView mStickyList;
private SwipeRefreshLayout mSwipeLayout;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ThatListFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_that_list, container, false);
// Find the StickyListHeadersListView
mStickyList = (StickyListHeadersListView) view.findViewById(android.R.id.list);
// Find the SwipeRefreshLayout
mSwipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
// This will not work, you have to create your own StickyListHeadersAdapter
ArrayAdapter mListAdapter = new StickyListHeadersAdapter(USE_YOUR_OWN);
// Set the adapter
mStickyList.setAdapter(mListAdapter);
// The fix to get the SwipeRefreshLayout to work properly with a sectioned header
mStickyList.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// The magic lays here. Get the listwrappers top point.
View childView = mStickyList.getWrappedList().getChildAt(0);
int top = (childView == null) ? 0 : childView.getTop();
// If at the absolute top then enable the SwipeRefreshLayout
if (top >= 0) {
mSwipeLayout.setEnabled(true);
} else {
mSwipeLayout.setEnabled(false);
}
}
});
// INIT SWIPE REFRESH LAYOUT
mSwipeLayout.setOnRefreshListener(this);
mSwipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
return view;
}
// SWIPEREFRESHLAYOUT
@Override
public void onRefresh() {
// Do the refreshing of the list.
// Disable the refreshing animation
mSwipeLayout.setRefreshing(false);
}
}
@Frikish
Copy link
Author

Frikish commented Apr 9, 2014

I'm sorry, but what do you mean by "adding an empty view for that list view"?

Did you set up the StickyListHeaders correctly? Do the list work correctly when there is no SwipeRefreshLayout?

@dvdrlee
Copy link

dvdrlee commented Apr 21, 2014

Thanks for this!

@aeatho
Copy link

aeatho commented Apr 23, 2014

the swpierefreshlayout isnot woking in frament!

@zokipirlo
Copy link

Thanks for that. You should also check if firstVisibleItem is 0, because childAt(0) returns first visible item. I'm using that with normal ListView.
if (firstVisibleItem == 0 && top >= 0)

@jgnt32
Copy link

jgnt32 commented Jul 7, 2014

public class StickyRefreshLayout extends SwipeRefreshLayout {
....
public boolean canChildScrollUp() {
    if(mListView == null){
        mListView =  ((StickyListHeadersListView) getChildAt(0)).getWrappedList();
    }

    if(mListView.getFirstVisiblePosition() == 0){
        View childView = mListView.getChildAt(0);
        int top = (childView == null) ? 0 : childView.getTop();
        return top < 0;
    } else {
        return true;
    }

}

thats better

@ClementHard
Copy link

Thanks, that solve my problem.

@ruslancpp
Copy link

Many Thanks.

@FireZenk
Copy link

FireZenk commented Mar 8, 2016

Thank you @jgnt32

@JianxunRao
Copy link

Thanks.This helps me a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment