Repository navigation
ReorderableListView#onReorder passes an unexpected new index #24786
Description
Activity
- addedframeworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.p: material_uimaterial_ui package in flutter/packagesmaterial_ui package in flutter/packages
on Nov 27, 2018 I'm having the exact same issue, almost a year after this issue was opened. I'm running stable channel, v1.9.1+hotfix.2
Is this being worked on? Seems like this widget is pretty much useless without this being fixed :)
There's an easy workaround.
Check this out:
https://stackoverflow.com/a/54164333/796963Funny (not really) that more than one year later this simple bug is still in the framework,,,
Hello, Flutter Team, are you going to do anything on that?..
Reacted by LX, RonyT and Guilherme GirottoThe workaround is a pretty big hack, and still doesn't work 100%. This really needs to get fixed.
Reacted by LXflutter doctor -v
[✓] Flutter (Channel dev, 1.19.0-0.0.pre, on Mac OS X 10.15.4 19E287, locale en-GB) • Flutter version 1.19.0-0.0.pre at /Users/tahatesser/Code/flutter_dev • Framework revision a849daf283 (3 days ago), 2020-05-07 18:59:02 -0700 • Engine revision 3953c3ccd1 • Dart version 2.9.0 (build 2.9.0-5.0.dev 4da5b40fb6) [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3) • Android SDK at /Users/tahatesser/Code/SDK • Platform android-29, build-tools 29.0.3 • ANDROID_HOME = /Users/tahatesser/Code/SDK • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 11.4.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.4.1, Build version 11E503a • CocoaPods version 1.9.1 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 3.6) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin version 45.1.1 • Dart plugin version 192.7761 • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211) [✓] VS Code (version 1.45.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.10.1 [✓] Connected device (4 available) • Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator) • macOS • macOS • darwin-x64 • Mac OS X 10.15.4 19E287 • Web Server • web-server • web-javascript • Flutter Tools • Chrome • chrome • web-javascript • Google Chrome 81.0.4044.138 • No issues found!- addedfound in release: 1.19Found to occur in 1.19Found to occur in 1.19has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work ona: qualityA truly polished experienceA truly polished experience
on May 11, 2020 - addedP2Important issues not at the top of the work listImportant issues not at the top of the work list
on May 29, 2020 I digged a bit into it. The indices in reorderable_list.dart are mainly used for the UI handling of the droppable space and don't represent the array position of the elements being dragged. But, and that is the problem, the indices are then used for the reorder callback.
// Places the value from startIndex one space before the element at endIndex. void reorder(int startIndex, int endIndex) { setState(() { if (startIndex != endIndex) widget.onReorder(startIndex, endIndex); // Animates leftover space in the drop area closed. // TODO(djshuckerow): bring the animation in line with the Material // specifications. _ghostController.reverse(from: 0.1); _entranceController.reverse(from: 0.1); _dragging = null; }); }A quick fix for the issue would be to decrease the endIndex if it is larger then the startIndex:
void reorder(int startIndex, int endIndex) { setState(() { if (startIndex != endIndex) { if(endIndex > startIndex) { endIndex -= 1; } widget.onReorder(startIndex, endIndex); } // Animates leftover space in the drop area closed. // TODO(djshuckerow): bring the animation in line with the Material // specifications. _ghostController.reverse(from: 0.1); _entranceController.reverse(from: 0.1); _dragging = null; }); }Can anyone take a look and give some thought's on that? I don't think it is a really nice solution, but it works.
Reacted by robindijkhof, Milen Marinov and LX22 remaining items
I believe that the 'most promising' interpretation for the
newIndexshould be that it represents the old index of the item that is now after the moved item. Then, the only annoying situation seems to be when we drag an item down and then place it back, which triggers theonReorderunnecessarily...This even applies to the OP's case and seems to make sense of why sometimes this value is equal to the List's
length(which would mean that none of the items is now after the moved item).At least this is what seems to happen to me using the current version.
$ flutter --version Flutter 2.2.1 • channel stable • https://github.com/flutter/flutter.git Framework • revision 02c026b03c (8 hours ago) • 2021-05-27 12:24:44 -0700 Engine • revision 0fdb562ac8 Tools • Dart 2.13.1Any working workaround on web?!
will it be correct to reduce 1 from newIndex if the item was moved from a lower index?
This is what I'm using that seems to be working in my testing.
array.insert(newIndex, array[oldIndex]); if (oldIndex < newIndex) { array.removeAt(oldIndex); } else { array.removeAt(oldIndex + 1); } setState(() {});I can't believe this bug is 2 years old
Reacted by Flucadetena, Jay Freeman (saurik), Guilherme Girotto, Arthur Araruna and Akay Berk | kanka.devReacted by Naim Bijapure, Tobias Heidingsfeld, Flucadetena, Jay Freeman (saurik), Guilherme Girotto and Akay Berk | kanka.devSame Issue, in my case when you move a Widget "higher" in the list, from 0 to 1, the "newIdx" comes wrong with a "+1". So instead of 1 you get 2. But when you move the widget "down" in the list, the values come wright. So my code looks like this:
onReorder: (oldIdx, newIdx) { Widget wid = widgets.removeAt(oldIdx); if (newIdx > oldIdx) widgets.insert(newIdx - 1, wid); else widgets.insert(newIdx, wid); setState(() {}); },Just discovered this bug for myself this morning. Surely the fix can't be very difficult to implement.
Reacted by Jay Freeman (saurik) and Tim LehmannReacted by Jay Freeman (saurik)- addedc: API breakBackwards-incompatible API changesBackwards-incompatible API changescustomer: crowdAffects or could affect many people, though not necessarily a specific customer.Affects or could affect many people, though not necessarily a specific customer.
on Nov 5, 2021 - changed the title
[-]ReorderableListView#onReorder passes an incorrect new index[/-][+]ReorderableListView#onReorder passes an unexpected new index[/+]on Nov 5, 2021 We've decided not to correct this issue because the obvious fix introduces a backwards incompatibility that can't be automatically corrected. More here: #93146 (comment)
I apologize for not resolving this quickly, when it would have been possible to just make the break.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.- locked as resolved and limited conversation to collaborators
on Feb 22, 2022
The
ReorderableListViewwidget seems to passing an incorrectnewIndexparameter when triggering theonReorderhandler.Steps to Reproduce
Here's a demo of the behavior as described in the below steps:
https://gist.github.com/chrislambe/b9aa44a5f3d3cc7dc6fdb24fb221982d
ReorderableListViewwidget and dummy data.onReorderhandler, print out the new index.1instead of0, even though the intent was to drop the item in its original position.childrenList.Logs
Result of above step 3
Result of above step 4
flutter analyzeflutter doctor -v