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.elevation,
|
||||
this.scrolledUnderElevation,
|
||||
this.notificationPredicate = defaultScrollNotificationPredicate,
|
||||
this.shadowColor,
|
||||
this.surfaceTintColor,
|
||||
this.shape,
|
||||
@ -197,6 +198,7 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
this.systemOverlayStyle,
|
||||
}) : assert(automaticallyImplyLeading != null),
|
||||
assert(elevation == null || elevation >= 0.0),
|
||||
assert(notificationPredicate != null),
|
||||
assert(primary != null),
|
||||
assert(toolbarOpacity != null),
|
||||
assert(bottomOpacity != null),
|
||||
@ -421,6 +423,13 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
/// shadow.
|
||||
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}
|
||||
/// The color of the shadow below the app bar.
|
||||
///
|
||||
@ -809,7 +818,7 @@ class _AppBarState extends State<AppBar> {
|
||||
}
|
||||
|
||||
void _handleScrollNotification(ScrollNotification notification) {
|
||||
if (notification is ScrollUpdateNotification && notification.depth == 0) {
|
||||
if (notification is ScrollUpdateNotification && widget.notificationPredicate(notification)) {
|
||||
final bool oldScrolledUnder = _scrolledUnder;
|
||||
final ScrollMetrics metrics = notification.metrics;
|
||||
switch (metrics.axisDirection) {
|
||||
|
@ -1011,6 +1011,53 @@ void main() {
|
||||
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', () {
|
||||
Widget buildSliverAppBar(bool forceElevated, {double? elevation, double? themeElevation}) {
|
||||
return MaterialApp(
|
||||
|
Loading…
x
Reference in New Issue
Block a user