# davideas/FlexibleAdapter: a decade of RecyclerView features in one adapter

> The library that pulled selection, headers, filtering, drag and swipe into a single RecyclerView adapter, and what its return to Maven Central in 2026 actually changed.

**davideas/FlexibleAdapter** — Fast and versatile Adapter for RecyclerView which regroups several features into one library to considerably improve the user experience :-)

- Repository: https://github.com/davideas/FlexibleAdapter
- Stars: 3,571 · Forks: 548
- Language: Java
- License: Apache-2.0
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/davideas-flexibleadapter

## A finished chapter and the problem it spent a decade on

RecyclerView arrived with a small contract. An adapter supplies items, a layout manager decides where they sit, and everything beyond that is yours to write. What FlexibleAdapter set out to fix was the everything beyond that: in app after app, the same problems kept being solved from scratch, and each solution arrived as a separate third party library that did not sit well next to the others.

The README is blunt about the motivation. The stated idea is to regroup multiple features in a unique library, without the need to customize and import several third libraries not compatible among them. The repository description says the same in fewer words: a fast and versatile Adapter for RecyclerView which regroups several features into one library.

The feature list explains why one library rather than five. Selection comes in simple, single and multi form. Items map to multiple view types through interfaces rather than a getItemViewType integer switch. Headers and sections carry sticky behaviour, elevation and collapsibility. There is expandable items with multi level expansion, drag and drop alongside swipe to dismiss, an endless scroll helper that avoids attaching a scroll listener, a customisable fast scroller, and an asynchronous filter that animates the result list and keeps the original list around.

The repository topics read like an index of that surface: expandable, draggable, swipeable, headers, footers, endless-scroll, fastscroll, multi-select, collapsible, selection-coherence, undo. The counts back the claim that it found an audience. 3,570 stars and 548 forks, with 53 issues still open.

## Wiring the dependencies after JCenter went away

Getting this library into a build was briefly impossible, and the reason is worth understanding because it shapes how you should read the current release numbers. The original artifacts were hosted on JCenter. When JCenter shut down, the old dependency coordinates resolved to a 404, and an application that had depended on them for years could no longer resolve a single class.

The 2026 release fixes exactly that. The core artifact is `eu.davidea:flexible-adapter:5.1.0`, with three optional siblings, the UI helper module, the LiveData module and the databinding module:

```gradle
dependencies {
    // Core library (required)
    implementation 'eu.davidea:flexible-adapter:5.1.0'

    // UI extensions (recommended)
    implementation 'eu.davidea:flexible-adapter-ui:1.0.0'

    // Optional extensions
    implementation 'eu.davidea:flexible-adapter-livedata:1.0.0'
    implementation 'eu.davidea:flexible-adapter-databinding:1.0.0'
}
```

The repository block it expects is deliberately plain, and the build was rebuilt for the occasion:

```gradle
repositories {
    mavenCentral()
}
```

The release notes for that build explain the move. To enable publication to Maven Central in 2026, the project was rebuilt with a modernised build system, and it now targets SDK 30 as the lowest level the tooling allowed. The floor for your own project is listed separately: compileSdk 30 or higher, Gradle 7.6, Android Gradle Plugin 7.4, JDK 11 and Kotlin 1.7. Those are low floors, chosen deliberately so that projects stuck on older toolchains could still resolve the artifact.

The size badge in the README gives the other number that matters for a mobile build. Core is 124 KB and the UI module adds 68 KB.

## The repository is four libraries and a sample app

The tree is small enough to read in one pass, and it explains how the features are packaged. The root holds the Gradle wrapper, `build.gradle`, `settings.gradle`, `publish.gradle` and `gradle.properties`, alongside the README, the LICENSE and an issue template. Everything else is a module directory:

```text
flexible-adapter/
flexible-adapter-ui/
flexible-adapter-livedata/
flexible-adapter-databinding/
flexible-adapter-app/
settings.gradle
build.gradle
publish.gradle
```

Only the first is required. The split is the interesting part, because it shows which features were considered genuinely core and which were situational enough to live outside. Selection, filtering, headers, expandable items and drag belong in the core, since any non trivial list can hit them. LiveData integration and databinding are opt in, because they tie you to a specific state management and view binding approach, and making them mandatory would have forced that choice on everyone.

The `flexible-adapter-app` module is the sample project, which makes it the fastest way to see any of this working rather than read about it.

One thing the repository does not carry is test code or a benchmark suite at the top level. The README claims high performance filtering and updates for medium and big lists and links to a wiki page for the measurement, but that page lives outside the repository. If list size is your concern, the honest answer is that the number to check is on the wiki, not here.

## Selection coherence is the feature the name hides

Look through the feature list and most entries are recognisable problems. One is not: selection coherence, which the README attaches to both expandable items and drag and drop.

The problem it solves is index drift. A RecyclerView adapter identifies items by position, so any operation that inserts, removes or reorders rows invalidates whatever the selection state was pointing at. Expand a parent and the children shift down by one. Drag row four to the top and every position between them changes. An adapter that tracks selection as a list of integers will now highlight the wrong rows, and it will usually do so silently.

FlexibleAdapter ties selection to the item objects rather than to raw positions, so an expand, a move or a filter run reconciles the selection instead of leaving it stale. The same mechanism covers drag and drop, where the item you picked up has to stay selected across the whole gesture while other rows move around it.

Filtering runs into the same wall, and the 2019 fix in the release notes is a small illustration of it. The adapter had been losing its filtered state when `updateDataSet` was called while a filter was active. The fix saves the current items as the original list and clears items while a filter is active, so a data refresh no longer wipes what the user had searched for.

Two other fixes from the same period are worth noting for anyone reading the diff between versions. Issue 716 was a null pointer in `applyAndAnimateRemovals`, and issue 655 was an expanded flag resetting incorrectly when a list started fully collapsed. Both are the kind of defect that only appears in an adapter, where state, position and animation all interact.

## What the helper module saves you from writing

The core library does the hard structural work, but a usable list screen needs a handful of surrounding behaviours that are tedious enough that most teams write them badly once. The `flexible-adapter-ui` module exists for those, and the README names them.

`ActionModeHelper` sets up selection mode, which otherwise means wiring a toolbar, a contextual action bar and a count display by hand every time. `UndoHelper` handles item restoration after a deletion, and the README points out that it works with expandable and swiped items too, which is the case where a naive undo stack breaks, because restoring the row is not the same as restoring its position in a hierarchy.

`EmptyViewHelper` covers the basic case of a list with nothing in it. It is listed as basic empty view handling rather than a full state machine, so a screen that needs distinct empty, loading and error states still has to branch those itself.

The remaining core helpers are worth naming because they replace code that looks trivial and turns out not to be. `LayoutUtils` handles orientation, span count and visible item calculations, which is what you need to decide whether to trigger endless scroll before the user reaches the bottom. There is support for third party layout managers, runtime position calculation for inserting or moving items inside a section, and custom tags for distinguishing multiple adapter instances during debugging, which matters more often than it sounds like it should.

## Why Jetpack Compose ended the question

The README opens by declaring FlexibleAdapter a legacy archive and calling it a finished chapter, and the reasoning given is not that the library was badly built. It is that the problem it solved stopped existing in the form it solved it.

Jetpack Compose replaced the adapter. Where this library needed a base adapter, item interfaces, a view type mapping and a set of helper classes to make a RecyclerView behave, Compose needs a lazy list and a composable per item. The README puts a number on it: what used to take hundreds of lines in this library now takes tens of lines of native Kotlin code.

That reframes the whole feature list. Sticky headers, multi level expansion, drag reordering, selection coherence: all of it is real work, and all of it is now something the platform or a smaller focused library handles. For a new Android only project the README points at `LazyColumn` and `LazyRow`. For a project targeting Android and iOS it points at Compose Multiplatform, and it is direct about the consequence: since FlexibleAdapter depends on the Android View system, it is not compatible with multiplatform targets.

So the library's value now splits cleanly in two. For an existing app still rendering XML layouts, it remains 100 percent stable, with an API frozen for years because it already fulfils its purpose. For anything starting from a blank project, the same features are cheaper to get from Compose, and the API you would be learning has no future.

The closing note is unambiguous. No further feature requests or pull requests will be processed, as the library is considered a finished product. The 2026 republication to Maven Central was framed as a last contribution to the community, there to restore distribution rather than to restart development.

## Conclusion

FlexibleAdapter is still a working dependency for an XML based Android app that needs sticky sections, drag reordering and multi select in one place, and the 2026 republication means it resolves from Maven Central instead of a dead JCenter URL. What it is not is a starting point: the README names LazyColumn and LazyRow as the path for new Android work and Compose Multiplatform for shared code, the API has been frozen since the 2018 AndroidX port, and 53 issues sit open with no plan for them. For a codebase already holding it, the useful next step is the 5.x wiki for the feature you are missing, not an upgrade.

## FAQ

### What version of FlexibleAdapter should I depend on?

Use eu.davidea:flexible-adapter:5.1.0 for the core library. The UI, LiveData and databinding extensions are separate artifacts at version 1.0.0. All four are AndroidX builds, republished to Maven Central in March 2026 after JCenter shut down.

### What are the minimum requirements for a project using FlexibleAdapter?

compileSdk 30 or higher, Gradle 7.6, Android Gradle Plugin 7.4, JDK 11 and Kotlin 1.7. The library targets SDK 30 as the lowest level its modernised build allows, and the README notes these floors were kept deliberately low.

### Is FlexibleAdapter still being maintained?

No. The README calls it a finished product, states that no further feature requests or pull requests will be processed, and recommends LazyColumn and LazyRow for new Android work. The last code push was 14 March 2026, which republished the existing artifact rather than adding features.

### Can FlexibleAdapter be used in a Kotlin Multiplatform project?

No. FlexibleAdapter depends on the Android View system, so it cannot be shared with an iOS target. The README directs multiplatform projects to Compose Multiplatform instead.

### What does selection coherence mean in FlexibleAdapter?

It is the mechanism that keeps selected items selected when the list structure changes underneath them, rather than tracking selection by position. The README attaches it to expandable items and to drag and drop, where rows shift and reorder during the interaction.

## Sources

- [davideas/FlexibleAdapter on GitHub](https://github.com/davideas/FlexibleAdapter)
- [Issues](https://github.com/davideas/FlexibleAdapter/issues)
- [License: Apache-2.0](https://github.com/davideas/FlexibleAdapter/blob/master/LICENSE)
- [README](https://github.com/davideas/FlexibleAdapter/blob/master/README.md)
- [Releases](https://github.com/davideas/FlexibleAdapter/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/davideas-flexibleadapter
