-
Notifications
You must be signed in to change notification settings - Fork 28.9k
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
Update the scrollbar #82687
Conversation
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! 🎉 |
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. :) |
Hey, @Piinks Could you please kick off the G-test again? Thanks ~ |
Sorry @xu-baolin it looks like I created some merge conflicts here. 😳 |
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 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.
@@ -1374,6 +1374,37 @@ void main() { | |||
); | |||
}); | |||
|
|||
testWidgets('The bar can show or hide when the viewport size change', (WidgetTester tester) async { |
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 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.
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.
OK, I will add more tests for the new events.
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.
Is this change still break the G-test or internal test?
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'll run the test suite with the latest commit. It only runs automatically after something has been approved.
haha, so interesting, this patch can also fix #84201
|
@@ -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 |
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 not sure if I have expressed it clearly,
it is likely that need your help to reorganize the language, thank you!
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 { |
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.
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.
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.
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() { |
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.
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. |
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.
/// Dispatches a notification that the contents metrics has changed. | |
/// Dispatches a notification that the [ScrollMetrics] have changed. |
/// 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. |
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 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. |
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.
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 { |
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'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 |
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.
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. |
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.
/// caused by the user scrolls. | |
/// caused by the user scrolling. |
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 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 |
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.
Just to avoid confusion aroudn the term window
/// window size changed. Press the floating action button to increase the | |
/// `windowSize` is changed. Press the floating action button to increase the |
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 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 |
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 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 |
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.
/// Creates a notification that the scrollable widget's [ScrollMetrics] has | |
/// Creates a notification that the scrollable widget's [ScrollMetrics] have |
(triage update) This is waiting on the reland of #85221, it was reverted. |
This can be updated now that the change has landed. 🎉 |
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! 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!
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).
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. |
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? |
@elliette hi, I have left some comments at flutter/devtools#3262, which may help you. |
@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? |
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?