Skip to content

Fix reorderable listview onreorder callback#59103

Closed
vagaone wants to merge 2 commits intoflutter:masterfrom
vagaone:fix_reorderable_listview_onreorder_callback
Closed

Fix reorderable listview onreorder callback#59103
vagaone wants to merge 2 commits intoflutter:masterfrom
vagaone:fix_reorderable_listview_onreorder_callback

Conversation

@vagaone
Copy link

@vagaone vagaone commented Jun 9, 2020

Description

This PR fixes the onReorder callback of ReorderableListView Widget

Related Issues

Fixes #24786

Tests

I added the following tests:

Removed the Workaround inside the reorderable_list_test.dart

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Did any tests fail when you ran them? Please read Handling breaking changes.

@fluttergithubbot fluttergithubbot added f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. labels Jun 9, 2020
@HansMuller HansMuller requested a review from perclasson June 12, 2020 18:47
@HansMuller
Copy link
Contributor

This PR's description needs to explain exactly what's wrong and ideally it should include a small test case that demonstrates the problem. The fix will need a regression test. Oftentimes the test case can (mostly) serve double duty as the basis for the regression test.

@vagaone
Copy link
Author

vagaone commented Jun 12, 2020

Ok, i will add the missing things on monday.

@HansMuller
Copy link
Contributor

Thanks, we appreciate the contribution!

Comment on lines -17 to -19
if (oldIndex < newIndex) {
newIndex -= 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

As Hans mentioned, I would suggest adding a test for:

  • Moving an item to the end in a list, and asserting that the newIndex is as expected
  • Moving an item to the start of a list, and asserting that the newIndex is as expected

Comment on lines -384 to +392
if (startIndex != endIndex)
widget.onReorder(startIndex, endIndex);
if (startIndex != endIndex) {
// the endindex is the index of the dragtarget
if(endIndex > startIndex) {
widget.onReorder(startIndex, endIndex -= 1);
} else {
widget.onReorder(startIndex, endIndex);
}

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be simplified. It seems as if endIndex is off by one, whenever we move an item towards the end of the list, due to us having a finalDropArea in the end of the list.

I think doing something like this will be more readable:

diff --git a/packages/flutter/lib/src/material/reorderable_list.dart b/packages/flutter/lib/src/material/reorderable_list.dart
index e11ca1273..70eaeb095 100644
--- a/packages/flutter/lib/src/material/reorderable_list.dart
+++ b/packages/flutter/lib/src/material/reorderable_list.dart
@@ -392,7 +392,9 @@ class _ReorderableListContentState extends State<_ReorderableListContent> with T

     // Drops toWrap into the last position it was hovering over.
     void onDragEnded() {
-      reorder(_dragStartIndex, _currentIndex);
+      final int endIndex = _currentIndex > _dragStartIndex ?
+        _currentIndex - 1 : _currentIndex;
+      reorder(_dragStartIndex, endIndex);
     }

     Widget wrapWithSemantics() {
@@ -401,11 +403,9 @@ class _ReorderableListContentState extends State<_ReorderableListContent> with T

       // Create the appropriate semantics actions.
       void moveToStart() => reorder(index, 0);
-      void moveToEnd() => reorder(index, widget.children.length);
+      void moveToEnd() => reorder(index, widget.children.length - 1);
       void moveBefore() => reorder(index, index - 1);
-      // To move after, we go to index+2 because we are moving it to the space
-      // before index+2, which is after the space at index+1.
-      void moveAfter() => reorder(index, index + 2);
+      void moveAfter() => reorder(index, index + 1);

       final MaterialLocalizations localizations = MaterialLocalizations.of(context);

Copy link
Contributor

@perclasson perclasson Jun 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: I see now that the current behavior seems to be expected and that the documentation already mentions this, see theReorderCallback: https://api.flutter.dev/flutter/material/ReorderCallback.html

This change is a breaking change to the API, and it will cause internal tests to break. See the page Handle breaking changes for how to proceed with this change. An idea is to put this behind an opt in flag (for example ReorderableListView.fixOnReorderEndIndex = false) for now until we can migrate those customers to avoid this change being reverted.

See this PR for an example for how we can add a flag (shouldSnackBarIgnoreFABRect ) to opt in behaviour: https://github.com/flutter/flutter/pull/50597/files

See also the same PR for how an migration guide was added to help future developers:
#50597

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first, thank you for your review. So i will try to sum things up that need to be done:

  1. Add a better Description for this PR
  2. Add the opt-in flag
  3. Rollback the commited test, to restore the current behaviour (with flag set to false)
  4. Add new tests, that use the opt-in flag
  5. Add the suggestet tests (move item to the end, move item to the start)
  6. Add a migration guide

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right, great, thanks!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am currently a bit stuck on the tests. There are very much tests, that are testing the reordering mechanisms in several constellations (like LTR, RTL, vertical, and so on) . Should i just add some basic tests, that demonstrate the new behaviour, when the fixOnReorderEndIndex flag is set, or should i cover all those cases?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding just one or two regression tests is good enough, to confirm the correct behaviour. The old tests would cover the rest.

For example:

  • Test for moving an item downwards with the correct onReoder endIndex.
  • Test for moving an item upwards with the correct onReoder endIndex.
  • Test that when you are just dragging and item into the same spot as it was before, ensure that onReoder is not called. Then you can also add a comment:
    ``// This is a regression test for https://github.com/flutter/flutter/issues/24786.`

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also reuse the old tests, by adding a for loop to test the behaviour with your flag and without. Perhaps that makes it easier?

An example of that is here: https://github.com/flutter/flutter/blob/master/packages/flutter/test/painting/gradient_test.dart#L819

@Piinks Piinks added the a: quality A truly polished experience label Jul 6, 2020
@perclasson
Copy link
Contributor

It seems like this PR will not be done? If so I will go ahead and close the PR. Please let me know if you are intending on continuing the work.

@perclasson perclasson added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jul 31, 2020
@perclasson perclasson closed this Aug 3, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

a: quality A truly polished experience f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants