sticky-headers-recyclerview

by timehop

[UNMAINTAINED] Sticky Headers decorator for Android's RecyclerView

3.7K Stars 765 Forks Last release: Not found Apache License 2.0 124 Commits 1 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

This project is no longer being maintained

sticky-headers-recyclerview

This decorator allows you to easily create section headers for RecyclerViews using a LinearLayoutManager in either vertical or horizontal orientation.

Credit to Emil Sjölander for creating StickyListHeaders, a library that many of us relied on for sticky headers in our listviews.

Here is a quick video of it in action (click to see the full video):

animated gif demo

animated gif demo

Download

Current version: Maven Central

compile 'com.timehop.stickyheadersrecyclerview:library:[latest.version.number]@aar'

Usage

There are three main classes,

StickyRecyclerHeadersAdapter
,
StickyRecyclerHeadersDecoration
, and
StickyRecyclerHeadersTouchListener
.

StickyRecyclerHeadersAdapter
has a very similar interface to the
RecyclerView.Adapter
, and it is recommended that you make your
RecyclerView.Adapter
implement
StickyRecyclerHeadersAdapter
.

There interface looks like this:

public interface StickyRecyclerHeadersAdapter {
  public long getHeaderId(int position);

public VH onCreateHeaderViewHolder(ViewGroup parent);

public void onBindHeaderViewHolder(VH holder, int position);

public int getItemCount(); }

The second class,

StickyRecyclerHeadersDecoration
, is where most of the magic happens, and does not require any configuration on your end. Here's an example from
onCreate()
in an activity:
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mAdapter = new MyStickyRecyclerHeadersAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
mRecyclerView.addItemDecoration(new StickyRecyclerHeadersDecoration(mAdapter));

StickyRecyclerHeadersTouchListener
allows you to listen for clicks on header views. Simply create an instance of
StickyRecyclerHeadersTouchListener
, set the
OnHeaderClickListener
, and add the
StickyRecyclerHeadersTouchListener
as a touch listener to your
RecyclerView
.
StickyRecyclerHeadersTouchListener touchListener =
    new StickyRecyclerHeadersTouchListener(recyclerView, headersDecor);
touchListener.setOnHeaderClickListener(
    new StickyRecyclerHeadersTouchListener.OnHeaderClickListener() {
      @Override
      public void onHeaderClick(View header, int position, long headerId) {
        Toast.makeText(MainActivity.this, "Header position: " + position + ", id: " + headerId,
            Toast.LENGTH_SHORT).show();
      }
    });
mRecyclerView.addOnItemTouchListener(touchListener);

The StickyHeaders aren't aware of your adapter so if you must notify them when your data set changes.

    mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
      @Override public void onChanged() {
        headersDecor.invalidateHeaders();
      }
    });

If the Recyclerview's layout manager implements getExtraLayoutSpace (to preload more content then is visible for performance reasons), you must implement ItemVisibilityAdapter and pass an instance as a second argument to StickyRecyclerHeadersDecoration's constructor.

java
    @Override
    public boolean isPositionVisible(final int position) {
        return layoutManager.findFirstVisibleItemPosition() <= position
            && layoutManager.findLastVisibleItemPosition() >= position;
    }

Item animators don't play nicely with RecyclerView decorations, so your mileage with that may vary.

Compatibility

API 11+

Known Issues

  • The header views aren't recycled at this time. Contributions are most welcome.

  • I haven't tested this with ItemAnimators yet.

  • The header views are drawn to a canvas, and are not actually a part of the view hierarchy. As such, they can't have touch states, and you may run into issues if you try to load images into them asynchronously.

Version History

0.4.3 (12/24/2015) - Change minSDK to 11, fix issue with header bounds caching

0.4.2 (8/21/2015) - Add support for reverse

ReverseLayout
in
LinearLayoutManager
by AntonPukhonin

0.4.1 (6/24/2015) - Fix "dancing headers" by DarkJaguar91

0.4.0 (4/16/2015) - Code reorganization by danoz73, fixes for different sized headers, performance improvements

0.3.6 (1/30/2015) - Prevent header clicks from passing on the touch event

0.3.5 (12/12/2014) - Add StickyRecyclerHeadersDecoration.invalidateHeaders() method

0.3.4 (12/3/2014) - Fix issues with rendering of header views with header ID = 0

0.3.3 (11/13/2014) - Fixes for padding, support views without headers

0.3.2 (11/1/2014) - Bug fixes for list items with margins and deleting items

0.2 (10/3/2014) - Add StickyRecyclerHeadersTouchListener

0.1 (10/2/2014) - Initial Release

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.