sectioned-recycler-view
This library allows you to divide items in your RecyclerView into groups called sections. Each section is represented by an adapter and can have a header. SectionAdapter is similar to Android’s RecyclerView.Adapter, which creates and binds ViewHolders. The header can be pinned, which means, that it will be displayed at the top of the RecyclerView above the corresponding section items. Pinned headers change automatically while scrolling or after dataset changes. You can also customize item swiping behavior for each section individually.
Advantages
- Simplicilty. Classes provided by this library are similar to Android ones.
- Flexibility. Your RecyclerView stays compatible with almost any external third-party library or API.
- Floating headers feature. An iOS style floating header behaves the same way as an item in the RecyclerView, so you don't have to handle the interaction with it separately.
- Swiping feature. You can customize item swiping behavior for each section individually.
- ViewHolders reusing. List item ViewHolders are reused as usual, pinned headers are cached and reused with the help of own implementation.
Usage
Setup
The Gradle dependency is available via jCenter. Add this to your module's build.gradle
file:
Initialization
Initialize your RecyclerView
with a successor of LinearLayoutManager
:
Create SectionDataManager
and set its adapter to the RecyclerView
:
After that you can use SectionDataManager
that implements SectionManager
interface to add/remove/replace sections in your RecyclerView
.
Adapters
This is an example of an adapter for a simple section without header:
It uses the following ItemViewHolder
:
As you can see, these classes are similar to Android’s RecyclerView.Adapter and RecyclerView.ViewHolder.
Adapter for a section with header has some additional methods to override:
When different sections have the same header (HeaderViewHolder
and its view), it can be reused by the RecyclerView
. To indicate it, you should pass equal header types to the SectionDataManager
when adding your SectionAdapter
and different ones otherwise:
Floating headers
To use floating headers feature, you have to place your RecyclerView
into SectionHeaderLayout
in your xml file:
To enable displaying pinned headers, attach SectionHeaderLayout
to your RecyclerView
and SectionDataManager
:
Now you can manage header pinned state with your adapter:
You can disable disaplying pinned headers any time by calling:
Note, that you should NOT update header view contents manually (e.g., while handling click event), because when header is pinned to the top, its view is duplicated and these changes won't affect the original item in the RecyclerView
. You should call notifyHeaderChanged()
instead to guarantee that your changes will be applied to both views while binding.
Swiping behavior
You can customize item swiping behavior for each section individually. To enable this feature, create ItemTouchHelper
initialized with SectionDataManager
's callback and attach it to your RecyclerView
:
Implement SectionItemSwipeCallback
, which is similar to Android's ItemTouchHelper.Callback:
You can specify it when adding a section or set/remove it later via SectionDataManager
:
Note, that section headers are unswipeable.
GridLayoutManager
When using GridLayoutManager
set SpanSizeLookup
as follows to display full width section headers:
It uses SectionDataManager
's implementation of PositionManager
to determine whether the item at the given position is a header.
Extra
- The number of sections you can add to the
SectionDataManager
during its lifetime is limited to 32,767. - Sections added via
SectionDataManager
are indexed beginning with the zero subscript and can be accessed by their index later. - Any
ViewHolder
can callgetGlobalAdapterPosition()
orgetGlobalLayoutPosition()
to access its positions in the globalRecyclerView
adapter among items of all sections including their headers. It also can get the index of the section it belongs to, which is calculated based on the adapter position, callinggetSection()
. ItemViewHolder
can retrieve its position in the corresponding adapter by callinggetSectionAdapterPosition()
.
The methods above can return -1 when theViewHolder
is not used in anyRecyclerView
.- For compatibility with future Android
RecyclerView
APIs and other libraries you can usePositionManager
interface to manage positions (e.g., retrieved from realViewHolder
) yourself.