这是indexloc提供的服务,不要输入任何密码
Skip to content

Update the scrollbar #82687

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

Merged
merged 1 commit into from
Jul 30, 2021
Merged

Update the scrollbar #82687

merged 1 commit into from
Jul 30, 2021

Conversation

xu-baolin
Copy link
Member

@xu-baolin xu-baolin commented May 17, 2021

Fixes #75613
Fixes #67690

I try to introduce a new ScrollContentMetricsNotification event to perceive the metric changes of the scrollable widget.

TODO: need more tests.

@Piinks Hi, What do you think of this?

@flutter-dashboard flutter-dashboard bot added the framework flutter/packages/flutter repository. See also f: labels. label May 17, 2021
@google-cla google-cla bot added the cla: yes label May 17, 2021
@Piinks
Copy link
Contributor

Piinks commented May 17, 2021

Ooooo This looks very interesting! Let me test it out with a few of the use cases folks have been reporting. I'll fire off the G tests as well to check for potential breaks. Thanks again @xu-baolin! You are a consistently excellent contributor! 🎉

@goderbauer goderbauer requested a review from Piinks May 19, 2021 21:44
@Piinks
Copy link
Contributor

Piinks commented Jun 3, 2021

Hey @xu-baolin I've been away for a bit, I've just fired off the Google tests to see if this is breaking there so we can see about moving forward. :)

@xu-baolin
Copy link
Member Author

Hey, @Piinks Could you please kick off the G-test again? Thanks ~

@Piinks Piinks added the f: scrolling Viewports, list views, slivers, etc. label Jun 10, 2021
@Piinks
Copy link
Contributor

Piinks commented Jun 10, 2021

Sorry @xu-baolin it looks like I created some merge conflicts here. 😳
I am forking this today to test out against a couple of the other use cases we discussed. :)

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

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

This is really great. I have tested it against a bunch of the various reports we have gotten and it is a very nice solution. Thank you @xu-baolin! Let me know what you think about the options for keeping or eliminating the type cast you mentioned.

@Piinks Piinks added a: desktop Running on desktop platform-web Web applications specifically labels Jun 15, 2021
@@ -1374,6 +1374,37 @@ void main() {
);
});

testWidgets('The bar can show or hide when the viewport size change', (WidgetTester tester) async {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add another test like this, where rather than changing the content (inside of SingleChildScrollView), it changes the size of the window around it just to verify it works both ways? I think you can do this easiest by just wrapping it with a media query and altering the media query data.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, I will add more tests for the new events.

Copy link
Member Author

Choose a reason for hiding this comment

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

Is this change still break the G-test or internal test?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll run the test suite with the latest commit. It only runs automatically after something has been approved.

@xu-baolin
Copy link
Member Author

xu-baolin commented Jun 16, 2021

haha, so interesting, this patch can also fix #84201
The new events trigger the remote Material widget to re-layout!

onNotification: (LayoutChangedNotification notification) {

@@ -898,6 +914,15 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
UserScrollNotification(metrics: copyWith(), context: context.notificationContext!, direction: direction).dispatch(context.notificationContext);
}

/// Dispatches a notification that the contents metrics has changed.
///
/// This notification is dispatched when the dimensions of the contents have
Copy link
Member Author

Choose a reason for hiding this comment

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

I am not sure if I have expressed it clearly,
it is likely that need your help to reorganize the language, thank you!

@Piinks Piinks added the c: new feature Nothing broken; request for a new capability label Jun 17, 2021
@Piinks
Copy link
Contributor

Piinks commented Jun 17, 2021

haha, so interesting, this patch can also fix #84201
The new events trigger the remote Material widget to re-layout!

onNotification: (LayoutChangedNotification notification) {

Awesome!! 🥳

@@ -942,3 +967,27 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
description.add('viewport: ${_viewportDimension?.toStringAsFixed(1)}');
}
}

/// A notification that a [Scrollable] widget's contents metrics has changed.
class ScrollContentMetricsNotification extends LayoutChangedNotification with ViewportNotificationMixin {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
class ScrollContentMetricsNotification extends LayoutChangedNotification with ViewportNotificationMixin {
class ScrollMetricsNotification extends LayoutChangedNotification with ViewportNotificationMixin {

Let's remove reference to 'content' since it may not be the content that has changed, but something else like the window resizing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Some sample code would be good too. I think in the dartpad embed, you can change the window size, so folks could see this in action.

@@ -508,6 +509,17 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
ScrollMetrics? _lastMetrics;
Axis? _lastAxis;

bool _isContentMetricsChanged() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
bool _isContentMetricsChanged() {
bool _isMetricsChanged() {

Same here and elsewhere, removing reference to content.

@@ -898,6 +914,15 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
UserScrollNotification(metrics: copyWith(), context: context.notificationContext!, direction: direction).dispatch(context.notificationContext);
}

/// Dispatches a notification that the contents metrics has changed.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Dispatches a notification that the contents metrics has changed.
/// Dispatches a notification that the [ScrollMetrics] have changed.

Comment on lines 919 to 921
/// This notification is dispatched when the dimensions of the contents have
/// changed. For example, the size of the child changed or new children were
/// load when scrolling a long list.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// This notification is dispatched when the dimensions of the contents have
/// changed. For example, the size of the child changed or new children were
/// load when scrolling a long list.
/// 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.

How does that sound? We should probably also document how this is different from ScrollNotification.

@@ -942,3 +967,27 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
description.add('viewport: ${_viewportDimension?.toStringAsFixed(1)}');
}
}

/// A notification that a [Scrollable] widget's contents metrics has changed.
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar updates to the docs here. Also, discuss how this is different from the other ScrollNotifications.

@@ -1374,6 +1374,37 @@ void main() {
);
});

testWidgets('The bar can show or hide when the viewport size change', (WidgetTester tester) async {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'll run the test suite with the latest commit. It only runs automatically after something has been approved.


print('call me.');
if (_isMetricsChanged()) {
// It isn't safe to trigger the ScrollMetricsNotification if we are in
Copy link
Member Author

Choose a reason for hiding this comment

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

Currently in the layout stage, and we can not fire an event to the developer.

///
/// 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 scrolls.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// caused by the user scrolls.
/// caused by the user scrolling.

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

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

This is looking really great. Thank you so much!
Can we split it in to two changes though? I think we should land the new ScrollMetricsNotification first (here) and then implement it in the scrollbar in a follow up change. Especially since this can fix more than one issue, we should keep them separate in case of potential reverts.

///
/// {@tool dartpad --template=freeform}
/// This sample shows that the [ScrollMetricsNotification] dispatched when the
/// window size changed. Press the floating action button to increase the
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to avoid confusion aroudn the term window

Suggested change
/// window size changed. Press the floating action button to increase the
/// `windowSize` is changed. Press the floating action button to increase the

Copy link
Contributor

Choose a reason for hiding this comment

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

This is an excellent example by the way.

/// caused by the user scrolls.
///
/// {@tool dartpad --template=freeform}
/// This sample shows that the [ScrollMetricsNotification] dispatched when the
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// This sample shows that the [ScrollMetricsNotification] dispatched when the
/// This sample shows that how a [ScrollMetricsNotification] is dispatched when the

/// ```
/// {@end-tool}
class ScrollMetricsNotification extends LayoutChangedNotification with ViewportNotificationMixin {
/// Creates a notification that the scrollable widget's [ScrollMetrics] has
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Creates a notification that the scrollable widget's [ScrollMetrics] has
/// Creates a notification that the scrollable widget's [ScrollMetrics] have

@xu-baolin
Copy link
Member Author

@Piinks hey, I have posted a new PR #85221 to land the new event.

@Piinks
Copy link
Contributor

Piinks commented Jun 30, 2021

(triage update) This is waiting on the reland of #85221, it was reverted.

@Piinks
Copy link
Contributor

Piinks commented Jul 28, 2021

This can be updated now that the change has landed. 🎉
I am waiting on it to roll to dev to ensure it is not reverted as well.

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

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

LGTM! This can land now. Thank you very much for sticking with this! You came up with a great solution and then did a lot of work to get it landed. Your contributions are always very much appreciated!

@elliette
Copy link
Member

Hi! I’m adding a horizontal scrollbar to the source file view in the Flutter devtools’ debugger: flutter/devtools#3262

I’m seeing very different behavior when using the stable Flutter SDK (which doesn’t include this change), and my local fork of Flutter (which includes this change).

  • Without this change: If the viewport starts out small enough that a horizontal scrollbar is required, and then is resized so that the scrollbar is no longer needed, the scrollbar will still be visible but it won’t do anything.

  • With this change: If the viewport starts out big enough that a horizontal scrollbar is not required, and then is resized smaller so that a scrollbar is now needed, no scrollbar will show up.

It seems like the scrollbar is being removed in cases where it shouldn't? Thanks!

@xu-baolin
Copy link
Member Author

Hi! I’m adding a horizontal scrollbar to the source file view in the Flutter devtools’ debugger: flutter/devtools#3262

I’m seeing very different behavior when using the stable Flutter SDK (which doesn’t include this change), and my local fork of Flutter (which includes this change).

  • Without this change: If the viewport starts out small enough that a horizontal scrollbar is required, and then is resized so that the scrollbar is no longer needed, the scrollbar will still be visible but it won’t do anything.
  • With this change: If the viewport starts out big enough that a horizontal scrollbar is not required, and then is resized smaller so that a scrollbar is now needed, no scrollbar will show up.

It seems like the scrollbar is being removed in cases where it shouldn't? Thanks!

@elliette Hey, it would be better if you could provide a minimal sample code. I will investigate as soon as possible.

@xu-baolin
Copy link
Member Author

Without this change: If the viewport starts out small enough that a horizontal scrollbar is required, and then is resized so that the scrollbar is no longer needed, the scrollbar will still be visible but it won’t do anything.

This behavior is also not expected, right?

@xu-baolin
Copy link
Member Author

@elliette hi, I have left some comments at flutter/devtools#3262, which may help you.

@efraimbart
Copy link

efraimbart commented Oct 3, 2021

@xu-baolin Should this notification go out for a list view when items are added below the viewport? I can't seem to get it to work in that case.

@xu-baolin
Copy link
Member Author

@xu-baolin Should this notification go out for a list view when items are added below the viewport? I can't seem to get it to work in that case.

It should work, can you provide a sample code to reproduce the case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: desktop Running on desktop c: new feature Nothing broken; request for a new capability f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. platform-web Web applications specifically
Projects
None yet
5 participants