-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Fix 25807: implement move in sliver multibox widget #29188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
goderbauer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a specific test for the bug you are fixing?
|
I have not written the tests yet, this will require a big numbers of tests. I would like to get some feedback on this implementation first before I proceed to write tests. I added a new callback to pageview and sliverchildelegator api called getChildIndex, this callback will take in a key and return index, -1 if not found. If not provided, the keepalive will not work if reordering the children. |
goderbauer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am excited about this fix! Thanks for working on this.
|
Please also take a look at the complains the analyzer has on this change (https://cirrus-ci.com/task/6257872051634176) and it looks like some existing tests are failing. |
2311378 to
1c57a8d
Compare
|
addressed all comments, ready for re-review without tests tho |
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
|
Refactored, and addressed all comments, ready for review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indicate -> Indicates
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
|
addressed all comments! ready for review! |
goderbauer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty good. It may be time to add (a lot of) tests! :)
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
|
Also, please take a look at the analyzer complains: https://cirrus-ci.com/task/5949177652576256 and the failing tests on cirrus. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figure this assert in assert is more informative than return false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could also replace the entire if with return !_debugChildIntegrityEnabled || _debugDanglingKeepAlives.isEmpty
certainly in any case you don't want both ! and isNotEmpty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you do the bool thing below, this would become:
return _debugVerifyChildOrder() && (!_debugChildIntegrityEnabled || _debugDanglingKeepAlives.isEmpty);
|
fixed existing tests and addressed all comments |
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deal with under flow case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hat do you mean by "there should be no swapping"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extraneous blank line
(general advice: it's often useful to self-review a patch to catch this kind of thing.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can rephrase this as the following for less code duplication:
RenderBox child = firstChild;
int index;
while (child != null) {
index = indexOf(child);
child = childAfter(child);
assert(child == null || indexOf(child) > index);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(also removes the need for the if)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you only call this from asserts, so you could make it return bool instead (return null in release builds), and have more idiomatic call sites.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for example then this just becomes assert(_debugVerifyChildOrder());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible that if we have only one child in the render tree with slot 0 and is in our viewport.
If we move the child to slot1.
The super.move will not do anything nor markNeedsLayout since there is only one child and the position does not change in the childList, but we still need to relayout the screen since that child is no longer in slot 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
grammar nits:
in the childList
call super.move (no the)
with the new slot
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's clearer to write this as:
childManager.didAdoptChild(child); // updates the slot in the parentDataThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please update the documentation for didAdoptChild to mention this new contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update the first sentence, but I think the original documentation is good enough?
/// Subclasses must ensure that the [SliverMultiBoxAdaptorParentData.index]
/// field of the child's [RenderObject.parentData] accurately reflects the
/// child's index in the child list after this function returns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this code doesn't make sense. (it already didn't make sense before your change. you're not making it worse.)
It means that while a warp is under way, we stop updating the tab page contents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we stop it here and rely on line 1233 to set it back I presume? It make sense to me although it is not a clean solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that if, say, there was an animation being driven in the tab, it would suddenly stop happening while you were switching tabs.
We really should fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep that a separate pr. This pr is already too complicated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you file an issue for changing that? I agree that it should be a separate PR since this one is already complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
206e3a6 to
ff222a4
Compare
goderbauer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Can you check why cirrus is unhappy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you file an issue for changing that? I agree that it should be a separate PR since this one is already complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. and reinsert back to _keepAliveBucket in the new slot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
|
all test passed @goderbauer @Hixie let me know when should i merge this, the breaking change email sent two days ago, haven't receive any objection yet |
Description
The sliver child currently does not have way to handle child reordering. It does not have a move functionality in its rendering class as well. This mean if children is reordered, it will treat every child as a new widget, reinitialize it and dispose the old one. This will be inefficient and will pose some problem with keep alive widget.
This pr implement the functionality to check and remap its children after reordering, and implement the logic to move its children rendering objects.
Related Issues
#25807
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.///).flutter analyze --flutter-repo) does not report any problems on my PR.Breaking Change
Does your PR require Flutter developers to manually update their apps to accommodate your change?
SliverChildListDelegator will default use non const constructor. Apps that use SliverChildListDelegator, or any widget that using SliverChildListDelegator and have initialized as a constant widget will break