Searchable ListView
An easy-to-use Flutter widget for adding a searchable, sortable, and paginated list UI. Supports synchronous lists, asynchronous data sources, expansion groups, slivers, pull-to-refresh, and many customization options.
Package: searchable_listview
Features
- Filter lists on edit or submit
- Support for async data sources and async filtering
- Expansion-group lists with searchable group contents
- Optional sort widget and custom sort predicate
- Pagination and
onPaginatecallback - Pull-to-refresh support
- Sliver-based scrolling effect
- Customizable loading / error / empty widgets
- Customizable search field (decoration, input type, icons, width/height)
- Auto-complete hints and secondary widgets next to the search field
Installation
Add the package to your pubspec.yaml:
dependencies:
searchable_listview: ^2.19.4
Then run:
flutter pub get
Quick Start
Basic synchronous list example:
SearchableList<Actor>(
initialList: actors,
itemBuilder: (actor) => ActorItem(actor: actor),
filter: (query) => actors
.where((a) => a.name.toLowerCase().contains(query.toLowerCase()))
.toList(),
emptyWidget: const Center(child: Text('No results')),
inputDecoration: InputDecoration(labelText: 'Search actor'),
)
Async list example
Use the .async constructor when data comes from a Future and you need to filter the returned list:
SearchableList<Actor>.async(
asyncListCallback: () async => await fetchActors(),
asyncListFilter: (query, list) =>
list.where((a) => a.name.contains(query)).toList(),
itemBuilder: (actor) => ActorItem(actor: actor),
loadingWidget: const Center(child: CircularProgressIndicator()),
errorWidget: const Center(child: Icon(Icons.error)),
)
Expansion groups
For grouped/expansion lists use the .expansion constructor:
SearchableList<Actor>.expansion(
expansionListData: mapOfActors,
expansionTitleBuilder: (key) => Text(key.toString()),
filterExpansionData: (query) => {
for (final entry in mapOfActors.entries)
entry.key: (mapOfActors[entry.key] ?? [])
.where((a) => a.name.contains(query))
.toList()
},
expansionListBuilder: (index, actor) => ActorItem(actor: actor),
)
Sliver list
Use .sliver to embed a searchable list inside sliver scroll views:
SearchableList<Actor>.sliver(
initialList: actors,
itemBuilder: (actor) => ActorItem(actor: actor),
filter: (q) => actors.where((a) => a.name.contains(q)).toList(),
)
Common Parameters
initialList— initial synchronous list of itemsfilter— synchronous filter callback (String -> ListasyncListCallback— Future that returns a ListasyncListFilter— filter that applies to results fromasyncListCallbackitemBuilder— builder for list item widgetsemptyWidget,loadingWidget,errorWidget— custom widgets for statesonPaginate— callback when list reaches the end (for pagination)inputDecoration,textStyle,textInputType— search field customizationsortWidget,sortPredicate— optional sorting UI and comparatorcloseKeyboardWhenScrolling— whether scrolling hides the keyboard
For a complete list of available parameters and detailed API, see the library documentation or the source code in lib/searchable_listview.dart.
Example App
See the example/ folder for a runnable demo with multiple configurations and screenshots.
Contributing
Contributions, issues and feature requests are welcome. Feel free to check the example/ folder for usage examples and open a pull request.
- Report bugs by opening an issue
- Suggest features by opening an issue
- Submit pull requests for fixes and improvements
Repository: github.com/koukibadr/Searchable-Listview
License
This project is licensed under the terms in the LICENSE file.