Introduce ScrollCacheExtent and also fixes unbound shrinkwrap cache ex…#181092
Introduce ScrollCacheExtent and also fixes unbound shrinkwrap cache ex…#181092auto-submit[bot] merged 16 commits intoflutter:masterfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a cacheExtentStyle property to ScrollView and related widgets, allowing the cacheExtent to be interpreted as pixels or as a multiplier of the viewport size. The changes are correctly wired through the widget and render layers. Additionally, it fixes an issue where an unbounded RenderShrinkWrappingViewport could cause a NaN value for the cache extent. The changes are well-tested with a new test file that covers various scroll views and the bug fix. My review includes one minor suggestion to improve the consistency of debug output.
08ad84b to
197b413
Compare
|
actually I should also refactor the use of a single parameter instead of two. convert to draft |
|
This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again. For more guidance, visit Writing a golden file test for Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
7db4dba to
57fc0f2
Compare
|
@gemini-code-assist code review |
There was a problem hiding this comment.
Code Review
This pull request introduces ScrollCacheExtent to provide a more robust API for defining cache extents, replacing the separate cacheExtent and cacheExtentStyle properties. This is a significant and well-executed refactoring that improves API clarity. The changes are applied consistently across various scrolling widgets. Additionally, the PR fixes a bug related to shrinkWrap causing a NaN value for the cache extent.
I've identified a critical issue in one of the new deprecated setters that would cause a compilation error, along with a couple of minor issues regarding efficiency and documentation. My review includes suggestions to address these points.
|
Hi @Piinks , this is ready for review |
There was a problem hiding this comment.
Code Review
This pull request introduces ScrollCacheExtent, a new class to define the cache area for scrollable content, replacing the separate cacheExtent and cacheExtentStyle properties. The change refactors numerous widgets, including ScrollView, ListView, GridView, PageView, and Viewport, to adopt this new API. The old properties are deprecated but handled for backward compatibility. Additionally, the PR fixes an issue in RenderShrinkWrappingViewport where an infinite mainAxisExtent could cause a NaN value for the cache extent. New tests are added to verify the functionality of scrollCacheExtent and the bug fix. My feedback includes a couple of minor suggestions for code cleanup.
|
google test doesn't seem related |
| /// | ||
| /// * [Viewport.scrollCacheExtent], which uses this class to define the cache area. | ||
| @immutable | ||
| sealed class ScrollCacheExtent { |
There was a problem hiding this comment.
This is so nice. Chef's kiss.
There was a problem hiding this comment.
WDYT about a ScrollCacheExtent that is for lazy loaders like RenderSliverList that allows the user to specify the number of children to lay out beyond the viewport bounds that are not visible?
Maybe something for later, not blocking.
There was a problem hiding this comment.
Meh, this might be harder. Here currently, both methods boil down to a pixel value.
Maybe for the other child-based idea, we should consider it a feature on lazy loader to ensure there is always one fully out of bounds child available to progress scroll forward or backward to. Just musing.
There was a problem hiding this comment.
by child count will be easier to implement with the new class. but the main problem with child count is that whether it is renderobject child count or semantics child count. By the use case of cache extent, it makes more sense to be by semantics child count. Such information is only available after semantics tree build, which is at the very end of the draw frame. That means we may need multiple run of layout to properly implement cache by semantics child count
Piinks
left a comment
There was a problem hiding this comment.
This is awesome. Thank you. 🙏
| const ScrollCacheExtent._(); | ||
|
|
||
| /// Creates a cache extent in logical pixels. | ||
| const factory ScrollCacheExtent.pixels(double pixels) = _PixelScrollCacheExtent; |
There was a problem hiding this comment.
Should we have a dart fix that transforms a previously set cacheExtent to this with the value provided as pixels?
There was a problem hiding this comment.
this will depends on cacheExtenType, is it possible to conditionally use different constructor based on whether the other parameter is set or not?
There was a problem hiding this comment.
Yes, in the fix, you should be able to check cacheExtent, cachExtentStyle, and then add the new parameter and provide the right constructor based on the values. Them you can use remove parameter to remove the old ones.
There was a problem hiding this comment.
Why don't we do the dart fix in a separate change? There are many classes to account for, and it might be a bit complicated.
| /// | ||
| /// * [Viewport.scrollCacheExtent], which uses this class to define the cache area. | ||
| @immutable | ||
| sealed class ScrollCacheExtent { |
There was a problem hiding this comment.
WDYT about a ScrollCacheExtent that is for lazy loaders like RenderSliverList that allows the user to specify the number of children to lay out beyond the viewport bounds that are not visible?
Maybe something for later, not blocking.
| /// | ||
| /// * [Viewport.scrollCacheExtent], which uses this class to define the cache area. | ||
| @immutable | ||
| sealed class ScrollCacheExtent { |
There was a problem hiding this comment.
Meh, this might be harder. Here currently, both methods boil down to a pixel value.
Maybe for the other child-based idea, we should consider it a feature on lazy loader to ensure there is always one fully out of bounds child available to progress scroll forward or backward to. Just musing.
| markNeedsLayout(); | ||
| } | ||
|
|
||
| // TODO(ianh): cacheExtent/cacheExtentStyle should be a single |
There was a problem hiding this comment.
Hooray for resolving old TODOs!
| double _attemptLayout(double mainAxisExtent, double crossAxisExtent, double correctedOffset) { | ||
| assert(!mainAxisExtent.isNaN); | ||
| assert(mainAxisExtent >= 0.0); | ||
| assert(mainAxisExtent.isFinite); |
There was a problem hiding this comment.
Is this safe to add? Does the infinite scroll view case take a different path?
There was a problem hiding this comment.
How does this differ from the shrink wrapping viewport below?
There was a problem hiding this comment.
can a viewport to be in a unbounded container? I thought that will throw an layout error. but i am not too sure
How does this differ from the shrink wrapping viewport below?
I think only shrink wrap viewport is allowed to be layout in unbound situation
There was a problem hiding this comment.
Ah yeah I see now. Normal viewport checks debugCheckHasBoundedAxis during computeDryLayout. Do you want to call that method instead of the assertion?
Shrinkwrapping does in fact allow infinite main axis extent. 👍
There was a problem hiding this comment.
debugCheckHasBoundedAxis checks against constraints which this method has already teared down into axis extent. I will keep this assert as is. let me know otherwise
There was a problem hiding this comment.
Right right! Gotcha. This assert should be ok then. 👍
485399e to
25109ea
Compare
Piinks
left a comment
There was a problem hiding this comment.
This LGTM. We can do the dart fix in a separate change 👍
I'll file an issue to follow up on the 2D scrolling package to migrate those when this gets to stable.
|
I will include dart fix since gemini finds it easy to add |
migration guide for flutter/flutter#181092 ## Presubmit checklist - [ ] If you are unwilling, or unable, to sign the CLA, even for a _tiny_, one-word PR, please file an issue instead of a PR. - [ ] If this PR is not meant to land until a future stable release, mark it as draft with an explanation. - [ ] This PR follows the [Google Developer Documentation Style Guidelines](https://developers.google.com/style)—for example, it doesn't use _i.e._ or _e.g._, and it avoids _I_ and _we_ (first-person pronouns). - [ ] This PR uses [semantic line breaks](https://github.com/dart-lang/site-shared/blob/main/doc/writing-for-dart-and-flutter-websites.md#semantic-line-breaks) of 80 characters or fewer. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Shams Zakhour <[email protected]>
f77b1b0 to
6776516
Compare
f785d54 to
50726eb
Compare
Oh my gosh. That's amazing |
Piinks
left a comment
There was a problem hiding this comment.
This LGTM!
Do you think we need a migration guide on the website?
Roll Flutter from e8f9dc50356d to 9bda20a11f1e (34 revisions) flutter/flutter@e8f9dc5...9bda20a 2026-02-10 [email protected] Remove Material import from focus_traversal_test.dart (flutter/flutter#180994) 2026-02-10 [email protected] Roll Skia from 6e217430c052 to cffb3bf918df (1 revision) (flutter/flutter#182131) 2026-02-10 [email protected] Encourage splitting large test files in testing documentation 2 (flutter/flutter#182051) 2026-02-10 [email protected] refactor: migrate CupertinoPageTransitionsBuilder to cupertino folder (flutter/flutter#179776) 2026-02-10 [email protected] Delete the last remaining skia only fragment shader tests (flutter/flutter#182127) 2026-02-10 [email protected] [a11y][android] Set new CheckState APIs for android API 36 (flutter/flutter#182113) 2026-02-10 [email protected] Add missing dependencies to framework_tests_misc_leak_tracking (flutter/flutter#181929) 2026-02-10 [email protected] Roll Dart SDK from eee0e2e11174 to 69eb951f8f7e (2 revisions) (flutter/flutter#182128) 2026-02-10 [email protected] Marks Linux_android_emu android_display_cutout to be flaky (flutter/flutter#181901) 2026-02-10 [email protected] Bump Dart to 3.10 (flutter/flutter#174066) 2026-02-10 [email protected] Roll Skia from d4b7e24a209b to 6e217430c052 (6 revisions) (flutter/flutter#182126) 2026-02-09 [email protected] Intercept UIScene device log and print a guided warning (flutter/flutter#181515) 2026-02-09 [email protected] Introduce ScrollCacheExtent and also fixes unbound shrinkwrap cache ex… (flutter/flutter#181092) 2026-02-09 [email protected] [Android] Add mechanism for setting Android engine flags via Android manifest (take 2) (flutter/flutter#181632) 2026-02-09 [email protected] Fix wrong comment about default impeller value (flutter/flutter#181831) 2026-02-09 [email protected] fix build fail for wayland only platform (flutter/flutter#182057) 2026-02-09 [email protected] [AGP 9] Added Warning Against Updating to AGP 9 (flutter/flutter#181977) 2026-02-09 [email protected] Updated Shaderc dep (flutter/flutter#180976) 2026-02-09 [email protected] Refactor accessibility guidelines out to widget layer (flutter/flutter#181672) 2026-02-09 [email protected] Roll Skia from 68dff53238e5 to d4b7e24a209b (2 revisions) (flutter/flutter#182087) 2026-02-09 [email protected] fix: OutlineInputBorder not respecting BorderSide stroke alignment (flutter/flutter#180487) 2026-02-09 [email protected] Adds opengles to engine dart tests (flutter/flutter#181933) 2026-02-09 [email protected] Add command to build a Swift Package for Add to App and generate FlutterPluginRegistrant (flutter/flutter#181224) 2026-02-09 [email protected] Remove unused constant in `bundle.dart` (flutter/flutter#182023) 2026-02-09 [email protected] Roll Fuchsia Linux SDK from iqtwdXlgKIyZkL5Li... to 7BGf7mPQvgLi7Axb6... (flutter/flutter#182082) 2026-02-09 [email protected] Remove unused getters in `user_messages.dart` (flutter/flutter#181867) 2026-02-09 [email protected] Roll Packages from 7805d3e to 3d5eaa5 (3 revisions) (flutter/flutter#182083) 2026-02-09 [email protected] Roll Skia from 5d891cd7fb7f to 68dff53238e5 (1 revision) (flutter/flutter#182080) 2026-02-09 [email protected] Update example description (flutter/flutter#182067) 2026-02-09 [email protected] Roll Dart SDK from 965b51c219d3 to eee0e2e11174 (1 revision) (flutter/flutter#182073) 2026-02-09 [email protected] Roll Skia from 9533d7533d59 to 5d891cd7fb7f (6 revisions) (flutter/flutter#182070) 2026-02-09 [email protected] Add a new flutter cli command, running-apps, using mDNS app discovery (flutter/flutter#180098) 2026-02-09 [email protected] Roll Skia from b7db9f35f0f2 to 9533d7533d59 (2 revisions) (flutter/flutter#182069) 2026-02-08 [email protected] Improve FlWindowMonitor API (flutter/flutter#181885) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 ...
…x… (flutter#181092) …tent NaN problem <!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> besides the general piping through parameters and breaking change. Fixing an issue when the shrinkwrap: true the mainAxisExetent will be double.infinity, which cause the cacheExtent to be double.Nan after the calculation and crash the app. ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…x… (flutter#181092) …tent NaN problem <!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> besides the general piping through parameters and breaking change. Fixing an issue when the shrinkwrap: true the mainAxisExetent will be double.infinity, which cause the cacheExtent to be double.Nan after the calculation and crash the app. ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…tent NaN problem
besides the general piping through parameters and breaking change. Fixing an issue when the shrinkwrap: true the mainAxisExetent will be double.infinity, which cause the cacheExtent to be double.Nan after the calculation and crash the app.
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.