sticky-headers-recyclerview
[UNMAINTAINED] Sticky Headers decorator for Android's RecyclerView
Top Related Projects
BRVAH:Powerful and flexible RecyclerAdapter
"Favor composition over inheritance" for RecyclerView Adapters
The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction...
Epoxy is an Android library for building complex screens in a RecyclerView
A SnapHelper that snaps a RecyclerView to an edge.
Flexible multiple types for Android RecyclerView.
Quick Overview
Sticky-headers-recyclerview is an Android library that provides a simple way to add sticky headers to RecyclerView. It allows headers to stick to the top of the list as the user scrolls, improving navigation and readability in long lists of data.
Pros
- Easy integration with existing RecyclerView implementations
- Supports both vertical and horizontal orientations
- Customizable header appearance and behavior
- Lightweight and efficient, with minimal impact on performance
Cons
- Limited documentation and examples
- Not actively maintained (last update was several years ago)
- May not be fully compatible with the latest Android versions or RecyclerView updates
- Lacks some advanced features found in newer alternatives
Code Examples
- Basic setup with a RecyclerView:
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
val adapter = YourAdapter()
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
// Add the StickyRecyclerHeadersDecoration
val headerDecor = StickyRecyclerHeadersDecoration(adapter)
recyclerView.addItemDecoration(headerDecor)
- Implementing the StickyRecyclerHeadersAdapter interface:
class YourAdapter : RecyclerView.Adapter<YourViewHolder>(), StickyRecyclerHeadersAdapter<HeaderViewHolder> {
override fun getHeaderId(position: Int): Long {
// Return a unique ID for each header
return items[position].headerId
}
override fun onCreateHeaderViewHolder(parent: ViewGroup): HeaderViewHolder {
// Create and return your header view holder
val view = LayoutInflater.from(parent.context).inflate(R.layout.header_item, parent, false)
return HeaderViewHolder(view)
}
override fun onBindHeaderViewHolder(holder: HeaderViewHolder, position: Int) {
// Bind data to your header view holder
holder.bind(items[position].headerData)
}
}
- Adding click listeners to headers:
val headerClickListener = StickyRecyclerHeadersTouchListener(recyclerView, headerDecor)
headerClickListener.setOnHeaderClickListener { view, position, headerId ->
// Handle header click
Toast.makeText(this, "Header $headerId clicked", Toast.LENGTH_SHORT).show()
}
recyclerView.addOnItemTouchListener(headerClickListener)
Getting Started
- Add the dependency to your
build.gradle
file:
dependencies {
implementation 'com.timehop.stickyheadersrecyclerview:library:0.4.3@aar'
}
- Implement the
StickyRecyclerHeadersAdapter
interface in your RecyclerView adapter. - Create and add the
StickyRecyclerHeadersDecoration
to your RecyclerView. - (Optional) Add header click listeners using
StickyRecyclerHeadersTouchListener
.
For more detailed instructions and advanced usage, refer to the project's GitHub repository.
Competitor Comparisons
BRVAH:Powerful and flexible RecyclerAdapter
Pros of BaseRecyclerViewAdapterHelper
- More comprehensive feature set, including drag & drop, animations, and multi-item types
- Actively maintained with frequent updates and a large community
- Extensive documentation and examples for easier implementation
Cons of BaseRecyclerViewAdapterHelper
- Steeper learning curve due to its extensive feature set
- May include unnecessary features for simpler projects, potentially increasing app size
- Less focused on sticky headers specifically, as it's a more general-purpose library
Code Comparison
sticky-headers-recyclerview:
mRecyclerView.addItemDecoration(new StickyRecyclerHeadersDecoration(mAdapter));
BaseRecyclerViewAdapterHelper:
public class MyAdapter extends BaseQuickAdapter<MyItem, BaseViewHolder> {
@Override
protected void convert(BaseViewHolder helper, MyItem item) {
// Bind data to views
}
}
BaseRecyclerViewAdapterHelper provides a more comprehensive approach to RecyclerView adapters, while sticky-headers-recyclerview focuses specifically on implementing sticky headers. The former offers a wider range of features but may require more setup, while the latter is simpler to implement for its specific use case.
Both libraries aim to enhance RecyclerView functionality, but BaseRecyclerViewAdapterHelper is more versatile and actively maintained, making it a better choice for projects requiring multiple advanced RecyclerView features beyond just sticky headers.
"Favor composition over inheritance" for RecyclerView Adapters
Pros of AdapterDelegates
- Promotes a more modular and flexible approach to RecyclerView adapters
- Easier to maintain and extend complex list structures
- Supports multiple view types with less boilerplate code
Cons of AdapterDelegates
- Requires additional setup and understanding of the delegation pattern
- May introduce slight performance overhead for simple list structures
- Less focused on specific features like sticky headers
Code Comparison
sticky-headers-recyclerview:
public class MyStickyHeaderAdapter extends StickyRecyclerHeadersAdapter<RecyclerView.ViewHolder> {
@Override
public long getHeaderId(int position) {
// Return header ID for position
}
@Override
public RecyclerView.ViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
// Create header view holder
}
}
AdapterDelegates:
public class MyAdapterDelegate extends AdapterDelegate<List<Object>> {
@Override
public boolean isForViewType(@NonNull List<Object> items, int position) {
// Determine if this delegate handles the view type
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
// Create view holder
}
}
The sticky-headers-recyclerview focuses on implementing sticky headers, while AdapterDelegates provides a more general-purpose solution for handling multiple view types in a RecyclerView. AdapterDelegates offers greater flexibility but requires more setup, whereas sticky-headers-recyclerview is more specialized for its specific use case.
The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction...
Pros of FastAdapter
- More comprehensive feature set, including drag & drop, swipe-to-dismiss, and multi-select
- Actively maintained with frequent updates and a larger community
- Supports a wider range of item types and layouts
Cons of FastAdapter
- Steeper learning curve due to its extensive functionality
- May be overkill for simpler projects that only need basic RecyclerView functionality
- Larger library size compared to sticky-headers-recyclerview
Code Comparison
FastAdapter:
val fastAdapter = FastAdapter.with(itemAdapter)
recyclerView.adapter = fastAdapter
itemAdapter.add(Item("Example"))
sticky-headers-recyclerview:
val adapter = StickyRecyclerHeadersAdapter(YourAdapter())
recyclerView.adapter = adapter
recyclerView.addItemDecoration(StickyRecyclerHeadersDecoration(adapter))
Summary
FastAdapter offers a more feature-rich solution for RecyclerView implementations, with active maintenance and a larger community. However, it may be more complex for simple use cases. sticky-headers-recyclerview provides a more focused solution for implementing sticky headers in RecyclerViews, with a simpler API but fewer additional features. The choice between the two depends on the specific requirements of your project and the level of functionality needed.
Epoxy is an Android library for building complex screens in a RecyclerView
Pros of Epoxy
- More comprehensive solution for building complex RecyclerViews
- Supports data binding and view binding out of the box
- Offers automatic diffing and efficient updates
Cons of Epoxy
- Steeper learning curve due to its extensive feature set
- Requires more setup and configuration
- May be overkill for simpler RecyclerView implementations
Code Comparison
Sticky-headers-recyclerview:
mRecyclerView.addItemDecoration(new StickyRecyclerHeadersDecoration(mAdapter));
Epoxy:
EpoxyRecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setController(new MyEpoxyController());
Key Differences
- Sticky-headers-recyclerview focuses specifically on implementing sticky headers in RecyclerViews
- Epoxy provides a more holistic approach to building complex RecyclerViews with various features
- Sticky-headers-recyclerview is simpler to implement for its specific use case
- Epoxy offers more flexibility and power for handling diverse RecyclerView scenarios
Use Cases
- Choose Sticky-headers-recyclerview for quick implementation of sticky headers in a RecyclerView
- Opt for Epoxy when building complex, data-driven RecyclerViews with multiple view types and dynamic content
Community and Maintenance
- Epoxy is actively maintained by Airbnb and has a larger community
- Sticky-headers-recyclerview has fewer recent updates but remains a solid choice for its specific functionality
A SnapHelper that snaps a RecyclerView to an edge.
Pros of GravitySnapHelper
- Provides smooth snapping behavior for RecyclerView items
- Supports multiple orientations (horizontal, vertical, and grid)
- Offers customizable snap positions (start, center, end)
Cons of GravitySnapHelper
- Focuses on snapping functionality rather than sticky headers
- May require additional implementation for header-specific features
- Limited to snapping behavior, lacking advanced header management
Code Comparison
GravitySnapHelper:
val snapHelper = GravitySnapHelper(Gravity.START)
snapHelper.attachToRecyclerView(recyclerView)
sticky-headers-recyclerview:
StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(mAdapter);
recyclerView.addItemDecoration(headersDecor);
Summary
GravitySnapHelper excels in providing smooth snapping behavior for RecyclerView items, supporting multiple orientations and customizable snap positions. However, it lacks specific functionality for sticky headers, which is the primary focus of sticky-headers-recyclerview. The latter offers more advanced header management features but may not provide the same level of snapping capabilities. Developers should choose based on their specific requirements for item snapping versus header management in their RecyclerView implementations.
Flexible multiple types for Android RecyclerView.
Pros of MultiType
- Supports multiple view types in a single RecyclerView adapter
- Easier to add new item types without modifying existing code
- More flexible and extensible architecture
Cons of MultiType
- Doesn't provide built-in sticky header functionality
- May require more initial setup for simple use cases
- Learning curve for understanding the concept of ItemViewBinders
Code Comparison
MultiType:
class TextItemViewBinder : ItemViewBinder<TextItem, TextItemViewBinder.ViewHolder>() {
override fun onCreateViewHolder(inflater: LayoutInflater, parent: ViewGroup): ViewHolder {
return ViewHolder(inflater.inflate(R.layout.item_text, parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, item: TextItem) {
holder.textView.text = item.text
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView: TextView = itemView.findViewById(R.id.text)
}
}
sticky-headers-recyclerview:
public class MyStickyHeaderAdapter extends StickyRecyclerHeadersAdapter<RecyclerView.ViewHolder> {
@Override
public long getHeaderId(int position) {
// Return ID for header based on position
}
@Override
public RecyclerView.ViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
// Create header view holder
}
@Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder, int position) {
// Bind header view holder
}
}
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
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):
Download
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<VH extends RecyclerView.ViewHolder> {
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.
@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
Top Related Projects
BRVAH:Powerful and flexible RecyclerAdapter
"Favor composition over inheritance" for RecyclerView Adapters
The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction...
Epoxy is an Android library for building complex screens in a RecyclerView
A SnapHelper that snaps a RecyclerView to an edge.
Flexible multiple types for Android RecyclerView.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot