-
Notifications
You must be signed in to change notification settings - Fork 26.8k
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
Fix scrolling in the Drawer
and NavigationDrawer
triggers AppBar's scrolledUnderElevation
#122600
Fix scrolling in the Drawer
and NavigationDrawer
triggers AppBar's scrolledUnderElevation
#122600
Conversation
? (drawerTheme.shape ?? defaults.shape) | ||
: (drawerTheme.endShape ?? defaults.endShape)), | ||
child: child, | ||
child: NotificationListener<Notification>( |
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 does not feel right, the issue is coming from ScrollNotifications, and this feels a bit too broad.
When wrapping an the Drawer or NavigationDrawer with own NotificationListener, allowNotifications can enable notification bubbling.
This feels like a foot gun for developers, because they can then reintroduce the issue if they do not stop the notification from bubbling up themselves.
Why not just add a ScrollNotificationObserver here and return true? If folks want to listen to notifications within the drawer, they can subscribe to the observer.
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 makes sense. I can revert the parameter. Thank you!
It only works when returning true
with Notification
for some reason.
This doesn't work
child: ScrollNotificationObserver(
child: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
return true;
},
child: ConstrainedBox(
This does
child: ScrollNotificationObserver(
child: NotificationListener<Notification>(
onNotification: (Notification notification) {
return true;
},
child: ConstrainedBox(
Even tho AppBar is looking for scroll notification, this is weird.
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 just had to change order... fixed this.
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 still stops any and all notifications from leaving the Drawer. I cannot think of anything in particular that would break as a result of this... but I am not sure.
@HansMuller what do you think?
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 suppose in most cases this would be safe, since the Drawer is usually part of the Scaffold, and usually nothing above the drawer cares if the Drawer is scrolling. I haven't looked at the history of this PR however it seems like it would be safer if the Scaffold squelched scroll notifications from the Drawer, rather than the Drawer doing it. It would still sort-of fail in the oddball case where there are nested scaffolds and was expected that scroll notifications from the inner Scaffold's Drawer would case the outer Scaffold to scroll. That seems like a pretty unlikely use case.
I suppose what we really need here is a way to identify the source of the notification. The AppBar only cares if the body of the Scaffold is 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.
I suppose what we really need here is a way to identify the source of the notification. The AppBar only cares if the body of the Scaffold is scrolling.
Notifications could be from any nested children in the body and I don't know if there is a way to filter all notifications from the body. ScrollNotificationObserver
seems to listen to all scroll notifications.
Since the app bar should not care about the scrolling notifications from the drawer.
What If we have a check like this inside the AppBar? This way we don't have squelched scroll notifications from the Drawers and AppBar can don't update MaterialState.scrolledUnder
if the drawer is open. Wdyt?
void _handleScrollNotification(ScrollNotification notification) {
if (notification is ScrollUpdateNotification && widget.notificationPredicate(notification)) {
final bool isAnyDrawerOpen = (notification.context?.findAncestorStateOfType<ScaffoldState>()?.isDrawerOpen ?? false)
|| (notification.context?.findAncestorStateOfType<ScaffoldState>()?.isEndDrawerOpen ?? false);
// If any drawer is open, don't change the scrolledUnder state.
if (!isAnyDrawerOpen) {
final bool oldScrolledUnder = _scrolledUnder;
final ScrollMetrics metrics = notification.metrics;
switch (metrics.axisDirection) {
case AxisDirection.up:
// Scroll view is reversed
_scrolledUnder = metrics.extentAfter > 0;
break;
case AxisDirection.down:
_scrolledUnder = metrics.extentBefore > 0;
break;
case AxisDirection.right:
case AxisDirection.left:
// Scrolled under is only supported in the vertical axis, and should
// not be altered based on horizontal notifications of the same
// predicate since it could be a 2D scroller.
break;
}
if (_scrolledUnder != oldScrolledUnder) {
setState(() {
// React to a change in MaterialState.scrolledUnder
});
}
}
}
}
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.
Notifications could be from any nested children in the body and I don't know if there is a way to filter all notifications from the body. ScrollNotificationObserver seems to listen to all scroll notifications.
ScrollNotification.context.findAncestorWidgetOfExactType could be used to write a predicate that returned true if the context was a descendant of the Scaffold's body (a predicate like Scaffold.isBodyDescendant(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.
That sounds really good. I just updated the PR with this suggestion.
allowNotifications
parameter to Drawer
and NavigationDrawer
Drawer
and NavigationDrawer
triggers AppBar's scrolledUnderElevation
6d2de20
to
a14dc22
Compare
a14dc22
to
e731e48
Compare
404aedb
to
94ab624
Compare
…s scrolledUnderElevation
94ab624
to
5392779
Compare
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.
Nice! LGTM!
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
This apparently caused a regression: #123782 Would it make sense to revert this while the regression is being worked on? |
@TahaTesser - Since the claim in #123782 is that scrolling performance is diminished by 10% for essentially all scrolls within an app with an AppBar, then - yes - we should revert this PR and find a way to avoid the performance penalty. |
… AppBar's scrolledUnderElevation (flutter#122600)" This reverts commit 6e04bdd.
Reverting this in #124187. |
…s scrolledUnderElevation (flutter#122600) Fix scrolling in the `Drawer` and `NavigationDrawer` triggers AppBar's scrolledUnderElevation
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
…rs AppBar's scrolledUnderElevation (flutter/flutter#122600)
fixes #120083
Description
This PR fixes the unexpected scrolledUnderElevation trigger when scrolling in the
Drawer
andNavigationDrawer
.code sample
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.