Skip to content

Conversation

@Piinks
Copy link
Contributor

@Piinks Piinks commented Apr 21, 2022

Fixes #102181
Necessary to re-land #101460

SingleChildScrollView has its own viewport render object, and only performs layout once (since it only has one child), so it never calls applyContentDimensions after the initial layout.

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.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@Piinks Piinks requested a review from darrenaustin April 21, 2022 22:20
@flutter-dashboard flutter-dashboard bot added f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. labels Apr 21, 2022
Copy link
Contributor

@darrenaustin darrenaustin left a comment

Choose a reason for hiding this comment

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

LGTM. Just a small question about the test.

// Scroll a bit
await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -100.0));

// We should have received a ScrollMetricsNotification
Copy link
Contributor

Choose a reason for hiding this comment

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

If there is only one notification, why is the counter 3 instead of 2?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This surprised me, TIL that tester.drag actually moves more than once. I can change this to a manual gesture so it's clearer. There are some other test updates I need to confirm as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

No worries, you could also just document that in this case there are two new notifications from the tester.drag call.

@Piinks Piinks requested a review from xu-baolin April 21, 2022 23:51
@Piinks
Copy link
Contributor Author

Piinks commented Apr 22, 2022

@xu-baolin can you take a look at this and let me know what you think? It looks like when you designed ScrollMetricsNotification, leaving out the SingleChildScrollView was intentional.

_didChangeViewportDimensionOrReceiveCorrection = false;
_pendingDimensions = true;
if (haveDimensions && !correctForNewDimensions(_lastMetrics!, currentMetrics!)) {
_maybeDispatchScrollMetricsNotification();
Copy link
Member

Choose a reason for hiding this comment

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

Why not let _RenderSingleChildViewport.performLayout response the return value like what RenderViewport.performLayout does?
It should do multi times otherwise the ScrollPosition has a wrong state, such as the _lastMetrics does not updated.

// Content dimensions do not change as SingleChildScrollView only lays out
// once, but the metrics can change based on scrolling and we may want to
// dispatch a ScrollMetricsNotification.
offset.applyContentDimensions(_minScrollExtent, _maxScrollExtent);
Copy link
Member

@xu-baolin xu-baolin Apr 22, 2022

Choose a reason for hiding this comment

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

According to the original design intent, ScrollMetricsNotification is to complement ScrollNotification, not to replace ScrollNotification. As the documentation says

/// For example, when the content of a scrollable is altered, making it larger
/// or smaller, this notification will be dispatched. Similarly, if the size
/// of the window or parent changes, the scrollable can notify of these
/// changes in dimensions.
///
/// The above behaviors usually do not trigger [ScrollNotification] events,
/// so this is useful for listening to [ScrollMetrics] changes that are not
/// caused by the user scrolling.

But would love to explore further how to revamp it. : )

@Piinks
Copy link
Contributor Author

Piinks commented Apr 22, 2022

Thanks for taking a look @xu-baolin! You gave me an idea for a different solution. Much appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ScrollMetricsNotification does not work with SingleChildScrollView

3 participants