-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Bottom sheet scrolling #21896
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
Bottom sheet scrolling #21896
Conversation
HansMuller
left a comment
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 apologize if a few of my comments are out of date; I started this review a week ago and just resumed now.
I've looked through everything except the tests
| /// | ||
| /// In most cases, this should be true. However, in the case of a parent | ||
| /// widget that will position this one based on its desired size (such as a | ||
| /// [MultiChildLayoutDelegate]), this should be set to false. |
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 seems like a somewhat obscure class to reference here. Maybe Center instead?
| /// related changes. When the extent of the sheet changes via a drag, | ||
| /// this notification bubbles up through the tree, which means a given | ||
| /// [NotificationListener] will recieve notifications for all descendant | ||
| /// [DraggableScrollableSheet] widgets. To focus on notifications form 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.
form => from
| _DraggableScrollableSheetState createState() => _DraggableScrollableSheetState(); | ||
| } | ||
|
|
||
| /// A [Notification] related to the position of the [DraggableScrollableSheet]. |
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.
maybe "size and scroll offset" instead of "position"? Ideally this one-line summary would make the meaning of "extent" clear.
| /// A [Notification] related to the position of the [DraggableScrollableSheet]. | ||
| /// | ||
| /// [DraggableScrollableSheet] widgets notify their ancestors about layout | ||
| /// related changes. When the extent of the sheet changes via a drag, |
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 we say something more specific than "layout related"?
| /// nearest [DraggableScorllableSheet] descendant, check that the [depth] | ||
| /// property of the notification is zero. | ||
| /// | ||
| /// When a extent notification is received by a [NotificationListener], 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.
a => an
| Future<void> close() { | ||
| assert(widget.animationController != null); | ||
| widget.animationController.reverse(); | ||
| widget.onClosing?.call(); |
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.
We usually write:
if (widget.onClosing != null)
widget.onClosing();
| /// By default, the widget will expand its non-occupied area to fill availble | ||
| /// space in the parent. If this is not desired, e.g. because the parent wants | ||
| /// to position sheet based on the space it is taking, the [expand] property | ||
| /// may be set ot false. |
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.
ot => to
| /// A widget that notifies a descendent [DraggableScrollableSheet] that it | ||
| /// should reset its position to the initial state. | ||
| /// | ||
| /// The [Scaffold] uses this widget to notify a persistententbottom sheet that |
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.
"persistent bottom sheet" or refer to a class/method
| /// the user has tapped back if the sheet has started to cover more of the body | ||
| /// than when at its initial position. This is important for users of assistive | ||
| /// technology, where dragging may be difficult to communicate. | ||
| class DraggableScrollableSheetResetter extends StatelessWidget { |
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.
We should chat about this name :-) On the up side it literally communicates its singular function. On the other hand ....
| @required this.child | ||
| }) : super(key: key); | ||
|
|
||
| /// The child to build that may contain a [DraggableScrollableSheet]. |
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 child's [DraggableScrollSheet] descendant will be reset when the static [reset] method is applied to a to context that includes it.
HansMuller
left a comment
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 with a few small potatoes comments
Hooray!
| this.animationController, | ||
| this.enableDrag = true, | ||
| this.elevation = 0.0, | ||
| this.color, |
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 hate to bring this up but, since showBottomSheet now has a backgroundColor parameter, maybe this should be called backgroundColor as well.
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| final MediaQueryData mediaQuery = MediaQuery.of(context); |
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.
Should assert here:
assert(debugCheckHasMediaQuery(context));
assert(debugCheckHasMaterialLocalizations(context));
| /// [DraggableScrollableSheet]. | ||
| /// | ||
| /// [DraggableScrollableSheet] widgets notify their ancestors when the size of | ||
| /// the sheet changes. When the extent of the sheet changes via a drag, |
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 a little tricky because we're talking about "size" and then "extent" in the next sentence. I think we need to defined what "extent" means at the outset of all of this.
| /// nearest [DraggableScorllableSheet] descendant, check that the [depth] | ||
| /// property of the notification is zero. | ||
| /// | ||
| /// When a extent notification is received by an [NotificationListener], 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.
a extent => an extent
an [NotificationListener] => a [NotificationListener]
| /// build or layout based on an extent notification would result in a layout | ||
| /// that lagged one frame behind, which is a poor user experience. Extent | ||
| /// notifications are used primarily to drive animations. The [Scaffold] widget | ||
| /// is an example of driving animations for the [FloatingActionButton] as 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.
maybe you mean that the Scaffold listens for extent notifications and responds by driving animations ...
| /// changed. | ||
| /// | ||
| /// All parameters are required. The [minExtent] must be >= 0. The [maxExtent] | ||
| /// must be <= 1.0. The [extent] must be between [minExtent] and [maxExtent]. |
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.
Doesn't initialExtent need to be between min/maxExtent
| } | ||
| } | ||
|
|
||
| /// A widget that notifies a descendent [DraggableScrollableSheet] that it |
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.
that notifies => that can notify
| expect(find.text('BottomSheet'), findsOneWidget); | ||
|
|
||
| await tester.pump(); // bottom sheet dismiss animation starts | ||
| await tester.pump(); // bottom sheet dismiss animation starts |
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.
extra space here
|
Thanks, @dnfield for sticking with this! Are any of the issues mentioned in the original post or other comments still existing? |
|
If there are, please file a bug. This should be good though. |
|
@dnfield Shouldn't this be DraggableScrollableBottomSheet? and shouldn't the name of the parameter be initialChildSizeRatio, not size? since 1 isn't a size, but a ratio. Same with the other parameters. Also, could we match the params of the other bottom sheets? Like the shape. Does this need to be a new issue? |
|
This initially was implemented to support horizontal scrolling as well, but was removed due to complexity and lack of solid use cases. It would be possible to reimplement |
|
And in general it's probably a bad idea to specify absolute heights for this wide, since it will show up on different screens and form factors. E.g. what if the phone is in landscape mode, or what if you're on a desktop or larger tablet |
|
Wouldn't that be our business to control? For example, I want a widget that works exactly like a bottomsheet that will cover most of my screen except the appbar. |
|
You can just specify it as a percentage of the available space |
|
I think it's because I thought this was a bottomsheet |
This is still a bit rough, but wanted to start getting some eyes on it.
Fixes #497
Here's what I know it still needs
Persistent sheets (e.g. setting theThis is resolved by tightening up an existing restriction to ensure that people can't show Standard Bottom Sheets if a persistent Bottom Sheet is already visible (and vice versa). Existing code had it covered the other way around, this just extends that. I suspect someone out there might want to do this, but I'm not sure it makes much sense design wise and it makes the code a lot more complicated.Scaffold.bottomSheet) need some work. Right now they're getting dismissed if another sheet gets dismissed.Right now, a developer has to pass a few parameters (setI think the refactor to aninitialTopto something valid, and setclampTopto true). This is the best I've been able to come up with so far - any attempts to automate that for developers result in some kind of bad result somewhere else.initialHeightPercentagesolves a lot of this.Ways existing widget is broken:
This is still WIP, but I think enough is done that it's worth getting some review/feedback.