The RecyclerView is one of the most used widgets in the Android world, and with it you have to implement an Adapter which provides the items for the view. Most use cases require the same base logic, but require you to write everything again and again.
The FastAdapter is here to simplify this process. You don't have to worry about the adapter anymore. Just write the logic for how your view/item should look like, and you are done. This library has a fast and highly optimized core which provides core functionality, most apps require. It also prevents common mistakes by taking away those steps from the devs. Beside being blazing fast, minimizing the code you need to write, it is also really easy to extend. Just provide another adapter implementation, hook into the adapter chain, custom select / deselection behaviors. Everything is possible.
- Core module 100% in Kotlin
- Click / Long-Click listeners
- Selection / Multi-Selection (MultiselectSample, CheckBoxSample, RadioButtonSample)
- Expandable items (ExpandableSample, IconGridSample ,AdvancedSample)
- Write less code, get better results
- Highly optimized code
- Simple Drag & Drop (SimpleItemListSample)
- Headers (StickyHeaderSample, AdvancedSample)
- Footers
- Filter (SimpleItemListSample)
- Includes suggestions from the Android Team
- Easily extensible
- Endless Scroll (EndlessScrollSample)
- "Leave-Behind"-Pattern (SwipeListSample)
- Split item view and model (ModelItem, MultiTypeModelItem)
- Chain other Adapters (SimpleItemListSample, StickyHeaderSample)
- Comes with useful Helpers
- ActionModeHelper (MultiselectSample)
- UndoHelper (MultiselectSample)
- More to come...
- FastScroller (external lib) (SimpleItemListSample)
You can try it out here Google Play (or download the latest release from GitHub)
- Kotlin | v4.0.0-rc01
- Java && AndroidX | v3.3.1
- Java && AppCompat | v3.2.9
The library is split up into core, commons, and extensions. The core functions are included in the following dependency.
implementation 'com.mikepenz:fastadapter:${latestFastAdapterRelease}'
implementation "androidx.appcompat:appcompat:${androidX}"
implementation "androidx.recyclerview:recyclerview:${androidX}"
Expandable support is included and can be added via this
implementation 'com.mikepenz:fastadapter-extensions-expandable:${latestFastAdapterRelease}'
//The tiny Materialize library used for its useful helper classes
implementation 'com.mikepenz:materialize:${latestVersion}' // at least 1.2.0
Many helper classes are included in the following dependency.
implementation 'com.mikepenz:fastadapter-extensions-diff:${latestFastAdapterRelease}' // diff util helpers
implementation 'com.mikepenz:fastadapter-extensions-drag:${latestFastAdapterRelease}' // drag support
implementation 'com.mikepenz:fastadapter-extensions-scroll${latestFastAdapterRelease}' // scroll helpers
implementation 'com.mikepenz:fastadapter-extensions-swipe:${latestFastAdapterRelease}' // swipe support
implementation 'com.mikepenz:fastadapter-extensions-ui:${latestFastAdapterRelease}' // pre-defined ui components
implementation 'com.mikepenz:fastadapter-extensions-utils:${latestFastAdapterRelease}' // needs the `expandable`, `drag` and `scroll` extension.
// required for the ui components and the utils
implementation "com.google.android.material:material:${androidX}"
//The tiny Materialize library used for its useful helper classes
implementation 'com.mikepenz:materialize:${latestVersion}' // at least 1.2.0
Major release, migrates fully to Kotlin. No migration notes yet available. Stay tuned!
Upgrades to use androidX dependencies. Use a version smaller than 3.3.x to use with appCompat dependencies.
v3 is a huge new release and comes with a big set of new changes. If you previously used the
FastAdapter
and head over to the MIGRATION GUIDE on how to get started with v3. In case you are searching v2.x head over here to it here.
Just create a class which extends the AbstractItem
as shown below. Implement the methods, and your item is ready.
public class SimpleItem extends AbstractItem<SimpleItem.ViewHolder> {
public String name;
public String description;
// The unique ID for this type of item
// The ID has to be unique per item type.
// This is important as it is used by the RV for viewHolder reusing.
@Override
public int getType() {
return R.id.fastadapter_sampleitem_id;
}
//The layout to be used for this type of item
@Override
public int getLayoutRes() {
return R.layout.sample_item;
}
@Override
public ViewHolder getViewHolder(@NonNull View v) {
return new ViewHolder(v);
}
/**
* our ViewHolder
*/
protected static class ViewHolder extends FastAdapter.ViewHolder<SimpleItem> {
@BindView(R.id.material_drawer_name)
TextView name;
@BindView(R.id.material_drawer_description)
TextView description;
public ViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
@Override
public void bindView(SimpleItem item, List<Object> payloads) {
StringHolder.applyTo(item.name, name);
StringHolder.applyToOrHide(item.description, description);
}
@Override
public void unbindView(SimpleItem item) {
name.setText(null);
description.setText(null);
}
}
}
//create the ItemAdapter holding your Items
ItemAdapter itemAdapter = new ItemAdapter();
//create the managing FastAdapter, by passing in the itemAdapter
FastAdapter fastAdapter = FastAdapter.with(itemAdapter);
//set our adapters to the RecyclerView
recyclerView.setAdapter(fastAdapter);
//set the items to your ItemAdapter
itemAdapter.add(ITEMS);
By default the FastAdapter
only provides basic functionality, which comes with the abstraction of items as Item
and Model
.
And the general functionality of adding/removing/modifying elements. To enable selections, or expandables the provided extensions need to be activated.
// Gets (or creates and attaches if not yet existing) the extension from the given `FastAdapter`
SelectExtension selectExtension = mFastAdapter.getOrCreateExtension(SelectExtension.class);
// configure as needed
selectExtension.setSelectable(true);
selectExtension.setMultiSelect(true);
selectExtension.setSelectOnLongClick(false);
// see the API of this class for more options.
This requires the
fastadapter-extensions-expandable
extension.
// Gets (or creates and attaches if not yet existing) the extension.
ExpandableExtension expandableExtension = fastItemAdapter.getOrCreateExtension(ExpandableExtension.class);
// configure as needed
expandableExtension.setOnlyOneExpandedItem(true);
For further details scroll down to the ExpandableItems
(under advanced usage) section.
fastAdapter.setOnClickListener((view, adapter, item, position) -> {
// Handle click here
return false;
});
//just add an `EventHook` to your `FastAdapter` by implementing either a `ClickEventHook`, `LongClickEventHook`, `TouchEventHook`, `CustomEventHook`
fastAdapter.addEventHook(new ClickEventHook<SimpleItem>() {
@Nullable
@Override
public View onBind(@NotNull RecyclerView.ViewHolder viewHolder) {
//return the views on which you want to bind this event
if (viewHolder instanceof SimpleItem.ViewHolder) {
return ((SimpleItem.ViewHolder) viewHolder).viewWhichReactsOnClick;
}
return null;
}
@Override
public void onClick(@NotNull View v, int position, @NotNull FastAdapter<SimpleItem> fastAdapter, @NotNull SimpleItem item) {
//react on the click event
}
});
// Call this in onQueryTextSubmit() & onQueryTextChange() when using SearchView
itemAdapter.filter("yourSearchTerm");
itemAdapter.getItemFilter().setFilterPredicate((item, constraint) -> {
return item.getName().startsWith(String.valueOf(constraint));
});
filter()
should return true for items to be retained and false for items to be removed.
This requires the
fastadapter-extensions-drag
extension.
First, attach ItemTouchHelper
to RecyclerView.
SimpleDragCallback dragCallback = new SimpleDragCallback();
ItemTouchHelper touchHelper = new ItemTouchHelper(dragCallback);
touchHelper.attachToRecyclerView(recyclerView);
Implement ItemTouchCallback
interface in your Activity, and override the itemTouchOnMove()
method.
@Override
public boolean itemTouchOnMove(int oldPosition, int newPosition) {
DragDropUtil.onMove(fastAdapter.getItemAdapter(), oldPosition, newPosition); // change position
return true;
}
Start by initializing your adapters:
// Head is a model class for your header
ItemAdapter<Header> headerAdapter = new ItemAdapter<>();
Initialize a Model FastAdapter:
ItemAdapter<IItem> itemAdapter = new ItemAdapter<>();
Finally, set the adapter:
FastAdapter fastAdapter = FastAdapter.with(headerAdapter, itemAdapter); //the order defines in which order the items will show up
// alternative the super type of both item adapters can be used. e.g.:
// FastAdapter<IItem> fastAdapter = FastAdapter.with(headerAdapter, itemAdapter);
recyclerView.setAdapter(fastAdapter);
Create a FooterAdapter. We need this to display a loading ProgressBar at the end of our list. (Don't forget to pass it into FastAdapter.with(..)
)
ItemAdapter<ProgressItem> footerAdapter = new ItemAdapter<>();
Keep in mind that ProgressItem is provided by FastAdapter’s extensions.
recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(footerAdapter) {
@Override
public void onLoadMore(int currentPage) {
footerAdapter.clear();
footerAdapter.add(new ProgressItem().withEnabled(false));
// Load your items here and add it to FastAdapter
fastAdapter.add(NEWITEMS);
}
});
For the complete tutorial and more features such as multi-select and CAB check out the sample app.
- As of v2.5.0 there are no more known requirements to use the
FastAdapter
with Proguard
The FastAdapter
comes with support for expandable items. After adding the dependency set up the Expandable
extension via:
expandableExtension = new ExpandableExtension<>();
fastAdapter.addExtension(expandableExtension);
Expandable items have to implement the IExpandable
interface, and the sub items the ISubItem
interface. This allows better support.
The sample app provides sample implementations of those. (Those in the sample are kept Model which allows them to be used with different parent / subitems)
As of the way how SubItems
and their state are handled it is highly recommended to use the identifier
based StateManagement
. Just add withPositionBasedStateManagement(false)
to your FastAdapter
setup.
A simple item just needs to extend from the AbstractExpandableItem
and provide the ViewHolder
as type.
public class SimpleSubExpandableItem extends AbstractExpandableItem<SimpleSubExpandableItem.ViewHolder> {
/**
* BASIC ITEM IMPLEMENTATION
*/
}
// See the SimpleSubExpandableItem.java
of the sample application for more details.
- RecyclerView Adapter made easy (FastAdapter v2.x)
Mike Penz:
- AboutLibraries https://github.com/mikepenz/AboutLibraries
- Android-Iconics https://github.com/mikepenz/Android-Iconics
- ItemAnimators https://github.com/mikepenz/ItemAnimators
- MaterialDrawer https://github.com/mikepenz/MaterialDrawer
Other Libs:
- Butterknife https://github.com/JakeWharton/butterknife
- Glide https://github.com/bumptech/glide
- MaterialScrollBar https://github.com/krimin-killr21/MaterialScrollBar
- StickyRecyclerHeadersAdapter https://github.com/timehop/sticky-headers-recyclerview
-
Mike Penz
-
Fabian Terhorst
This free, open source software was also made possible by a group of volunteers that put many hours of hard work into it. See the CONTRIBUTORS.md file for details.
I want to give say thanks to some special contributors who provided some huge PRs and many changes to improve this great library.
Copyright 2017 Mike Penz
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.