AppBar
: Fix nested scroll view doesn't update AppBar
elevation for Material 3 (#103899)
This commit is contained in:
parent
64cba0e417
commit
32157e3fcb
@ -162,6 +162,7 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
this.bottom,
|
this.bottom,
|
||||||
this.elevation,
|
this.elevation,
|
||||||
this.scrolledUnderElevation,
|
this.scrolledUnderElevation,
|
||||||
|
this.notificationPredicate = defaultScrollNotificationPredicate,
|
||||||
this.shadowColor,
|
this.shadowColor,
|
||||||
this.surfaceTintColor,
|
this.surfaceTintColor,
|
||||||
this.shape,
|
this.shape,
|
||||||
@ -197,6 +198,7 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
this.systemOverlayStyle,
|
this.systemOverlayStyle,
|
||||||
}) : assert(automaticallyImplyLeading != null),
|
}) : assert(automaticallyImplyLeading != null),
|
||||||
assert(elevation == null || elevation >= 0.0),
|
assert(elevation == null || elevation >= 0.0),
|
||||||
|
assert(notificationPredicate != null),
|
||||||
assert(primary != null),
|
assert(primary != null),
|
||||||
assert(toolbarOpacity != null),
|
assert(toolbarOpacity != null),
|
||||||
assert(bottomOpacity != null),
|
assert(bottomOpacity != null),
|
||||||
@ -421,6 +423,13 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
/// shadow.
|
/// shadow.
|
||||||
final double? scrolledUnderElevation;
|
final double? scrolledUnderElevation;
|
||||||
|
|
||||||
|
/// A check that specifies which child's [ScrollNotification]s should be
|
||||||
|
/// listened to.
|
||||||
|
///
|
||||||
|
/// By default, checks whether `notification.depth == 0`. Set it to something
|
||||||
|
/// else for more complicated layouts.
|
||||||
|
final ScrollNotificationPredicate notificationPredicate;
|
||||||
|
|
||||||
/// {@template flutter.material.appbar.shadowColor}
|
/// {@template flutter.material.appbar.shadowColor}
|
||||||
/// The color of the shadow below the app bar.
|
/// The color of the shadow below the app bar.
|
||||||
///
|
///
|
||||||
@ -809,7 +818,7 @@ class _AppBarState extends State<AppBar> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _handleScrollNotification(ScrollNotification notification) {
|
void _handleScrollNotification(ScrollNotification notification) {
|
||||||
if (notification is ScrollUpdateNotification && notification.depth == 0) {
|
if (notification is ScrollUpdateNotification && widget.notificationPredicate(notification)) {
|
||||||
final bool oldScrolledUnder = _scrolledUnder;
|
final bool oldScrolledUnder = _scrolledUnder;
|
||||||
final ScrollMetrics metrics = notification.metrics;
|
final ScrollMetrics metrics = notification.metrics;
|
||||||
switch (metrics.axisDirection) {
|
switch (metrics.axisDirection) {
|
||||||
|
@ -1011,6 +1011,53 @@ void main() {
|
|||||||
expect(getMaterial().elevation, 10);
|
expect(getMaterial().elevation, 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('scrolledUnderElevation with nested scroll view', (WidgetTester tester) async {
|
||||||
|
Widget buildAppBar({double? scrolledUnderElevation}) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(useMaterial3: true),
|
||||||
|
home: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Title'),
|
||||||
|
scrolledUnderElevation: scrolledUnderElevation,
|
||||||
|
notificationPredicate: (ScrollNotification notification) {
|
||||||
|
return notification.depth == 1;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
body: ListView.builder(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
itemCount: 4,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 600.0,
|
||||||
|
width: 800.0,
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: 100,
|
||||||
|
itemBuilder: (BuildContext context, int index) =>
|
||||||
|
ListTile(title: Text('Item $index')),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Material getMaterial() => tester.widget<Material>(find.descendant(
|
||||||
|
of: find.byType(AppBar),
|
||||||
|
matching: find.byType(Material),
|
||||||
|
));
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildAppBar(scrolledUnderElevation: 10));
|
||||||
|
// Starts with the base elevation.
|
||||||
|
expect(getMaterial().elevation, 0.0);
|
||||||
|
|
||||||
|
await tester.fling(find.text('Item 2'), const Offset(0.0, -600.0), 2000.0);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// After scrolling it should be the scrolledUnderElevation.
|
||||||
|
expect(getMaterial().elevation, 10);
|
||||||
|
});
|
||||||
|
|
||||||
group('SliverAppBar elevation', () {
|
group('SliverAppBar elevation', () {
|
||||||
Widget buildSliverAppBar(bool forceElevated, {double? elevation, double? themeElevation}) {
|
Widget buildSliverAppBar(bool forceElevated, {double? elevation, double? themeElevation}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user