Skip to content

Conversation

@chunhtai
Copy link
Contributor

@chunhtai chunhtai commented Mar 12, 2019

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.

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

Breaking Change

Does your PR require Flutter developers to manually update their apps to accommodate your change?

  • [ x] Yes, this is a breaking change (Please read Handling breaking changes).
    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
  • No, this is not a breaking change.

Copy link
Member

@goderbauer goderbauer left a 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?

@goderbauer goderbauer added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Mar 12, 2019
@chunhtai chunhtai requested review from HansMuller and Hixie March 22, 2019 17:07
@chunhtai
Copy link
Contributor Author

chunhtai commented Mar 22, 2019

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.

@chunhtai chunhtai changed the title Fix 25807: ensure globalkey for tabview children Fix 25807: implement move in sliver multibox widget Mar 22, 2019
Copy link
Member

@goderbauer goderbauer left a 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.

@goderbauer
Copy link
Member

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.

@chunhtai chunhtai force-pushed the issue/25807 branch 2 times, most recently from 2311378 to 1c57a8d Compare March 25, 2019 23:15
@chunhtai
Copy link
Contributor Author

chunhtai commented Mar 25, 2019

addressed all comments, ready for re-review

without tests tho

@chunhtai
Copy link
Contributor Author

Refactored, and addressed all comments, ready for review

@chunhtai chunhtai added the c: API break Backwards-incompatible API changes label Mar 27, 2019
Copy link
Member

Choose a reason for hiding this comment

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

Indicate -> Indicates

@chunhtai
Copy link
Contributor Author

addressed all comments! ready for review!

Copy link
Member

@goderbauer goderbauer left a 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! :)

@goderbauer
Copy link
Member

Also, please take a look at the analyzer complains: https://cirrus-ci.com/task/5949177652576256 and the failing tests on cirrus.

Copy link
Contributor Author

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

Copy link
Contributor

@Hixie Hixie Apr 9, 2019

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.

Copy link
Contributor

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);

@chunhtai
Copy link
Contributor Author

chunhtai commented Mar 29, 2019

fixed existing tests and addressed all comments

Copy link
Contributor Author

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

Copy link
Member

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"?

Copy link
Contributor

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.)

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 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);
}

Copy link
Contributor

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)

Copy link
Contributor

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.

Copy link
Contributor

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());

Copy link
Contributor

Choose a reason for hiding this comment

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

why?

Copy link
Contributor Author

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.

Copy link
Contributor

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

Copy link
Contributor

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 parentData

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@chunhtai chunhtai force-pushed the issue/25807 branch 2 times, most recently from 206e3a6 to ff222a4 Compare April 16, 2019 19:40
Copy link
Member

@goderbauer goderbauer left a 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?

Copy link
Member

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.

Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@chunhtai
Copy link
Contributor Author

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

@chunhtai chunhtai merged commit 77ab0b8 into flutter:master Apr 22, 2019
chunhtai added a commit to chunhtai/flutter that referenced this pull request Apr 23, 2019
chunhtai added a commit that referenced this pull request Apr 23, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

c: API break Backwards-incompatible API changes f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants