Deprecate onReorder callback
The onReorder callback has been deprecated in favor of a new callback, called onReorderItem.
Summary
#
The onReorder callback in the
ReorderableListView, ReorderableListView.builder,
ReorderableList, and SliverReorderableList widgets
has been replaced by a new callback, onReorderItem,
which provides more intuitive behavior for newIndex.
Background
#
The onReorder callback in the
ReorderableListView, ReorderableListView.builder,
ReorderableList, and SliverReorderableList widgets required
a manual correction for the second parameter, newIndex,
in case the oldIndex is before the newIndex because
the list of items would be shortened by one element.
void handleReorder(int oldIndex, int newIndex) {
if (oldIndex < newIndex) {
// Removing the item at oldIndex shortens the list by 1.
newIndex -= 1;
}
// Handle the actual reorder behavior...
}
ReorderableListView(
onReorder: handleReorder,
)
The new callback, onReorderItem, solves this problem
by doing the correction automatically.
void handleReorder(int oldIndex, int newIndex) {
// Handle the actual reorder behavior...
}
ReorderableListView(
onReorderItem: handleReorder,
)
Migration guide
#
The ReorderableListView, ReorderableListView.builder,
ReorderableList, and SliverReorderableList widgets
share the same reordering logic.
The same migration steps apply to each of these widgets.
This migration guide uses ReorderableListView as an example.
Case 1: Simple callbacks
#Code before migration:
ReorderableListView(
onReorder: (int oldIndex, int newIndex) {
if (oldIndex < newIndex) {
newIndex -= 1;
}
// Handle reorder ...
}
)
Code after migration:
ReorderableListView(
onReorder: (int oldIndex, int newIndex) {
if (oldIndex < newIndex) {
newIndex -= 1;
}
onReorderItem: (int oldIndex, int newIndex) {
// Handle reorder ...
}
)
Case 2: Opt out for complex onReorder implementations
#
In some cases, such as when the provided callback is complex,
the migration to the new onReorderItem callback might not be obvious.
In these cases, to opt out of the new behavior,
adjust the newIndex to match the old behavior.
Code before migration:
void handleSomeComplexReorder(int oldIndex, int newIndex) {
// Handle reorder ...
}
ReorderableListView(
onReorder: (int oldIndex, int newIndex) {
handleSomeComplexReorder(oldIndex, newIndex);
}
)
Code after migration:
void handleSomeComplexReorder(int oldIndex, int newIndex) {
// Handle reorder ...
}
ReorderableListView(
onReorder: (int oldIndex, int newIndex) {
onReorderItem: (int oldIndex, int newIndex) {
// To get the equivalent of the old newIndex:
if (oldIndex < newIndex) {
newIndex += 1;
}
return handleSomeComplexReorder(oldIndex, newIndex);
}
)
Timeline
#
Landed in version: 3.41.0-1.0.pre-364
In stable release: 3.44
References
#API documentation:
Relevant issues:
- The index parameter for ReorderableListView's onReorderCallback is confusing
- SliverReorderableList newIndex arg off by one on drag down list
Relevant PRs:
Unless stated otherwise, the documentation on this site reflects Flutter 3.44.0. Page last updated on 2026-05-20. View source or report an issue.