jskierbi
7/31/2014 - 8:29 PM

SwipeRefreshLayout and StickyListHeaders.md

Trying to find a solution

StickyListHeaders

SwipeRefreshLayout

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);

    }
}
<?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>