Unverified Commit 55801645 authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Re-land reverse case for AppBar scrolled under (#102343)

parent 3bd19f22
...@@ -767,17 +767,33 @@ class _AppBarState extends State<AppBar> { ...@@ -767,17 +767,33 @@ class _AppBarState extends State<AppBar> {
} }
void _handleScrollNotification(ScrollNotification notification) { void _handleScrollNotification(ScrollNotification notification) {
if (notification is ScrollUpdateNotification) { final bool oldScrolledUnder = _scrolledUnder;
final bool oldScrolledUnder = _scrolledUnder; final ScrollMetrics metrics = notification.metrics;
_scrolledUnder = notification.depth == 0
&& notification.metrics.extentBefore > 0 if (notification.depth != 0) {
&& notification.metrics.axis == Axis.vertical; _scrolledUnder = false;
if (_scrolledUnder != oldScrolledUnder) { } else {
setState(() { switch (metrics.axisDirection) {
// React to a change in MaterialState.scrolledUnder 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.
_scrolledUnder = false;
break;
} }
} }
if (_scrolledUnder != oldScrolledUnder) {
setState(() {
// React to a change in MaterialState.scrolledUnder
});
}
} }
Color _resolveColor(Set<MaterialState> states, Color? widgetColor, Color? themeColor, Color defaultColor) { Color _resolveColor(Set<MaterialState> states, Color? widgetColor, Color? themeColor, Color defaultColor) {
......
...@@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart'; ...@@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart';
import 'framework.dart'; import 'framework.dart';
import 'notification_listener.dart'; import 'notification_listener.dart';
import 'scroll_notification.dart'; import 'scroll_notification.dart';
import 'scroll_position.dart';
/// A [ScrollNotification] listener for [ScrollNotificationObserver]. /// A [ScrollNotification] listener for [ScrollNotificationObserver].
/// ///
...@@ -151,14 +152,26 @@ class ScrollNotificationObserverState extends State<ScrollNotificationObserver> ...@@ -151,14 +152,26 @@ class ScrollNotificationObserverState extends State<ScrollNotificationObserver>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return NotificationListener<ScrollNotification>( // A ScrollMetricsNotification allows listeners to be notified for an
onNotification: (ScrollNotification notification) { // initial state, as well as if the content dimensions change without
_notifyListeners(notification); // scrolling.
return NotificationListener<ScrollMetricsNotification>(
onNotification: (ScrollMetricsNotification notification) {
_notifyListeners(_ConvertedScrollMetricsNotification(
metrics: notification.metrics,
context: notification.context,
));
return false; return false;
}, },
child: _ScrollNotificationObserverScope( child: NotificationListener<ScrollNotification>(
scrollNotificationObserverState: this, onNotification: (ScrollNotification notification) {
child: widget.child, _notifyListeners(notification);
return false;
},
child: _ScrollNotificationObserverScope(
scrollNotificationObserverState: this,
child: widget.child,
),
), ),
); );
} }
...@@ -170,3 +183,10 @@ class ScrollNotificationObserverState extends State<ScrollNotificationObserver> ...@@ -170,3 +183,10 @@ class ScrollNotificationObserverState extends State<ScrollNotificationObserver>
super.dispose(); super.dispose();
} }
} }
class _ConvertedScrollMetricsNotification extends ScrollNotification {
_ConvertedScrollMetricsNotification({
required super.metrics,
required super.context,
});
}
...@@ -2567,311 +2567,457 @@ void main() { ...@@ -2567,311 +2567,457 @@ void main() {
expect(actionIconTheme.color, foregroundColor); expect(actionIconTheme.color, foregroundColor);
}); });
testWidgets('SliverAppBar.backgroundColor MaterialStateColor scrolledUnder', (WidgetTester tester) async { group('MaterialStateColor scrolledUnder', () {
const double collapsedHeight = kToolbarHeight; const double collapsedHeight = kToolbarHeight;
const double expandedHeight = 200.0; const double expandedHeight = 200.0;
const Color scrolledColor = Color(0xff00ff00); const Color scrolledColor = Color(0xff00ff00);
const Color defaultColor = Color(0xff0000ff); const Color defaultColor = Color(0xff0000ff);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
elevation: 0,
backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
return states.contains(MaterialState.scrolledUnder) ? scrolledColor : defaultColor;
}),
expandedHeight: expandedHeight,
pinned: true,
),
SliverList(
delegate: SliverChildListDelegate(
<Widget>[
Container(height: 1200.0, color: Colors.teal),
],
),
),
],
),
),
),
);
Finder findAppBarMaterial() { Finder findAppBarMaterial() {
return find.descendant(of: find.byType(AppBar), matching: find.byType(Material)); return find.descendant(of: find.byType(AppBar), matching: find.byType(Material)).first;
} }
Color? getAppBarBackgroundColor() { Color? getAppBarBackgroundColor(WidgetTester tester) {
return tester.widget<Material>(findAppBarMaterial()).color; return tester.widget<Material>(findAppBarMaterial()).color;
} }
expect(getAppBarBackgroundColor(), defaultColor); group('SliverAppBar', () {
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight); Widget _buildSliverApp({
required double contentHeight,
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0)); bool reverse = false,
await gesture.moveBy(const Offset(0.0, -expandedHeight)); bool includeFlexibleSpace = false,
await gesture.up(); }) {
await tester.pumpAndSettle(); return MaterialApp(
home: Scaffold(
expect(getAppBarBackgroundColor(), scrolledColor); body: CustomScrollView(
expect(tester.getSize(findAppBarMaterial()).height, collapsedHeight); reverse: reverse,
slivers: <Widget>[
gesture = await tester.startGesture(const Offset(50.0, 300.0)); SliverAppBar(
await gesture.moveBy(const Offset(0.0, expandedHeight)); elevation: 0,
await gesture.up(); backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
await tester.pumpAndSettle(); return states.contains(MaterialState.scrolledUnder)
? scrolledColor
expect(getAppBarBackgroundColor(), defaultColor); : defaultColor;
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight); }),
}); expandedHeight: expandedHeight,
pinned: true,
testWidgets('SliverAppBar.backgroundColor with FlexibleSpace MaterialStateColor scrolledUnder', (WidgetTester tester) async { flexibleSpace: includeFlexibleSpace
const double collapsedHeight = kToolbarHeight; ? const FlexibleSpaceBar(title: Text('SliverAppBar'))
const double expandedHeight = 200.0; : null,
const Color scrolledColor = Color(0xff00ff00);
const Color defaultColor = Color(0xff0000ff);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
elevation: 0,
backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
return states.contains(MaterialState.scrolledUnder) ? scrolledColor : defaultColor;
}),
expandedHeight: expandedHeight,
pinned: true,
flexibleSpace: const FlexibleSpaceBar(
title: Text('SliverAppBar'),
), ),
), SliverList(
SliverList( delegate: SliverChildListDelegate(
delegate: SliverChildListDelegate(
<Widget>[ <Widget>[
Container(height: 1200.0, color: Colors.teal), Container(height: contentHeight, color: Colors.teal),
], ],
),
), ),
), ],
],
),
),
),
);
Finder findAppBarMaterial() {
// There are 2 Material widgets below AppBar. The second is only added if
// flexibleSpace is non-null.
return find.descendant(of: find.byType(AppBar), matching: find.byType(Material)).first;
}
Color? getAppBarBackgroundColor() {
return tester.widget<Material>(findAppBarMaterial()).color;
}
expect(getAppBarBackgroundColor(), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, -expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, collapsedHeight);
gesture = await tester.startGesture(const Offset(50.0, 300.0));
await gesture.moveBy(const Offset(0.0, expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
});
testWidgets('AppBar.backgroundColor MaterialStateColor scrolledUnder', (WidgetTester tester) async {
const Color scrolledColor = Color(0xff00ff00);
const Color defaultColor = Color(0xff0000ff);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
return states.contains(MaterialState.scrolledUnder) ? scrolledColor : defaultColor;
}),
title: const Text('AppBar'),
),
body: ListView(
children: <Widget>[
Container(height: 1200.0, color: Colors.teal),
],
),
),
),
);
Finder findAppBarMaterial() {
return find.descendant(of: find.byType(AppBar), matching: find.byType(Material));
}
Color? getAppBarBackgroundColor() {
return tester.widget<Material>(findAppBarMaterial()).color;
}
expect(getAppBarBackgroundColor(), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, -kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
gesture = await tester.startGesture(const Offset(50.0, 300.0));
await gesture.moveBy(const Offset(0.0, kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
});
testWidgets('AppBar.backgroundColor with FlexibleSpace MaterialStateColor scrolledUnder', (WidgetTester tester) async {
const Color scrolledColor = Color(0xff00ff00);
const Color defaultColor = Color(0xff0000ff);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
return states.contains(MaterialState.scrolledUnder) ? scrolledColor : defaultColor;
}),
title: const Text('AppBar'),
flexibleSpace: const FlexibleSpaceBar(
title: Text('FlexibleSpace'),
), ),
), ),
body: ListView( );
children: <Widget>[ }
Container(height: 1200.0, color: Colors.teal),
], testWidgets('backgroundColor', (WidgetTester tester) async {
), await tester.pumpWidget(
), _buildSliverApp(contentHeight: 1200.0)
), );
);
expect(getAppBarBackgroundColor(tester), defaultColor);
Finder findAppBarMaterial() { expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
// There are 2 Material widgets below AppBar. The second is only added if
// flexibleSpace is non-null. TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
return find.descendant(of: find.byType(AppBar), matching: find.byType(Material)).first; await gesture.moveBy(const Offset(0.0, -expandedHeight));
} await gesture.up();
await tester.pumpAndSettle();
Color? getAppBarBackgroundColor() {
return tester.widget<Material>(findAppBarMaterial()).color; expect(getAppBarBackgroundColor(tester), scrolledColor);
} expect(tester.getSize(findAppBarMaterial()).height, collapsedHeight);
expect(getAppBarBackgroundColor(), defaultColor); gesture = await tester.startGesture(const Offset(50.0, 300.0));
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight); await gesture.moveBy(const Offset(0.0, expandedHeight));
await gesture.up();
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0)); await tester.pumpAndSettle();
await gesture.moveBy(const Offset(0.0, -kToolbarHeight));
await gesture.up(); expect(getAppBarBackgroundColor(tester), defaultColor);
await tester.pumpAndSettle(); expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
});
expect(getAppBarBackgroundColor(), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight); testWidgets('backgroundColor with FlexibleSpace', (WidgetTester tester) async {
await tester.pumpWidget(
gesture = await tester.startGesture(const Offset(50.0, 300.0)); _buildSliverApp(contentHeight: 1200.0, includeFlexibleSpace: true)
await gesture.moveBy(const Offset(0.0, kToolbarHeight)); );
await gesture.up();
await tester.pumpAndSettle(); expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
expect(getAppBarBackgroundColor(), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight); TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
}); await gesture.moveBy(const Offset(0.0, -expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, collapsedHeight);
gesture = await tester.startGesture(const Offset(50.0, 300.0));
await gesture.moveBy(const Offset(0.0, expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
});
testWidgets('backgroundColor - reverse', (WidgetTester tester) async {
await tester.pumpWidget(
_buildSliverApp(contentHeight: 1200.0, reverse: true)
);
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, collapsedHeight);
gesture = await tester.startGesture(const Offset(50.0, 300.0));
await gesture.moveBy(const Offset(0.0, -expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
});
testWidgets('backgroundColor with FlexibleSpace - reverse', (WidgetTester tester) async {
await tester.pumpWidget(
_buildSliverApp(
contentHeight: 1200.0,
reverse: true,
includeFlexibleSpace: true,
)
);
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, collapsedHeight);
gesture = await tester.startGesture(const Offset(50.0, 300.0));
await gesture.moveBy(const Offset(0.0, -expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
});
testWidgets('backgroundColor - not triggered in reverse for short content', (WidgetTester tester) async {
await tester.pumpWidget(
_buildSliverApp(contentHeight: 200, reverse: true)
);
// In reverse, the content here is not long enough to scroll under the app
// bar.
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
final TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
});
testWidgets('backgroundColor with FlexibleSpace - not triggered in reverse for short content', (WidgetTester tester) async {
await tester.pumpWidget(
_buildSliverApp(
contentHeight: 200,
reverse: true,
includeFlexibleSpace: true,
)
);
// In reverse, the content here is not long enough to scroll under the app
// bar.
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
final TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, expandedHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, expandedHeight);
});
});
testWidgets('AppBar._handleScrollNotification safely calls setState()', (WidgetTester tester) async { group('AppBar', () {
// Regression test for failures found in Google internal issue b/185192049. Widget _buildAppBar({
final ScrollController controller = ScrollController(initialScrollOffset: 400); required double contentHeight,
await tester.pumpWidget( bool reverse = false,
MaterialApp( bool includeFlexibleSpace = false
home: Scaffold( }) {
appBar: AppBar( return MaterialApp(
title: const Text('AppBar'), home: Scaffold(
), appBar: AppBar(
body: Scrollbar( elevation: 0,
isAlwaysShown: true, backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
controller: controller, return states.contains(MaterialState.scrolledUnder)
child: ListView( ? scrolledColor
controller: controller, : defaultColor;
}),
title: const Text('AppBar'),
flexibleSpace: includeFlexibleSpace
? const FlexibleSpaceBar(title: Text('FlexibleSpace'))
: null,
),
body: ListView(
reverse: reverse,
children: <Widget>[ children: <Widget>[
Container(height: 1200.0, color: Colors.teal), Container(height: contentHeight, color: Colors.teal),
], ],
), ),
), ),
), );
), }
);
testWidgets('backgroundColor', (WidgetTester tester) async {
expect(tester.takeException(), isNull); await tester.pumpWidget(
}); _buildAppBar(contentHeight: 1200.0)
);
testWidgets('AppBar scrolledUnder does not trigger on horizontal scroll', (WidgetTester tester) async {
const Color scrolledColor = Color(0xff00ff00); expect(getAppBarBackgroundColor(tester), defaultColor);
const Color defaultColor = Color(0xff0000ff); expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
await tester.pumpWidget( TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
MaterialApp( await gesture.moveBy(const Offset(0.0, -kToolbarHeight));
home: Scaffold( await gesture.up();
appBar: AppBar( await tester.pumpAndSettle();
elevation: 0,
backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) { expect(getAppBarBackgroundColor(tester), scrolledColor);
return states.contains(MaterialState.scrolledUnder) ? scrolledColor : defaultColor; expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
}),
title: const Text('AppBar'), gesture = await tester.startGesture(const Offset(50.0, 300.0));
), await gesture.moveBy(const Offset(0.0, kToolbarHeight));
body: ListView( await gesture.up();
scrollDirection: Axis.horizontal, await tester.pumpAndSettle();
children: <Widget>[
Container(height: 600.0, width: 1200.0, color: Colors.teal), expect(getAppBarBackgroundColor(tester), defaultColor);
], expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
});
testWidgets('backgroundColor with FlexibleSpace', (WidgetTester tester) async {
await tester.pumpWidget(
_buildAppBar(contentHeight: 1200.0, includeFlexibleSpace: true)
);
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, -kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
gesture = await tester.startGesture(const Offset(50.0, 300.0));
await gesture.moveBy(const Offset(0.0, kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
});
testWidgets('backgroundColor - reverse', (WidgetTester tester) async {
await tester.pumpWidget(
_buildAppBar(contentHeight: 1200.0, reverse: true)
);
await tester.pump();
// In this test case, the content always extends under the AppBar, so it
// should always be the scrolledColor.
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
gesture = await tester.startGesture(const Offset(50.0, 300.0));
await gesture.moveBy(const Offset(0.0, -kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
});
testWidgets('backgroundColor with FlexibleSpace - reverse', (WidgetTester tester) async {
await tester.pumpWidget(
_buildAppBar(
contentHeight: 1200.0,
reverse: true,
includeFlexibleSpace: true,
)
);
await tester.pump();
// In this test case, the content always extends under the AppBar, so it
// should always be the scrolledColor.
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
gesture = await tester.startGesture(const Offset(50.0, 300.0));
await gesture.moveBy(const Offset(0.0, -kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), scrolledColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
});
testWidgets('_handleScrollNotification safely calls setState()', (WidgetTester tester) async {
// Regression test for failures found in Google internal issue b/185192049.
final ScrollController controller = ScrollController(initialScrollOffset: 400);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('AppBar'),
),
body: Scrollbar(
isAlwaysShown: true,
controller: controller,
child: ListView(
controller: controller,
children: <Widget>[
Container(height: 1200.0, color: Colors.teal),
],
),
),
),
), ),
), );
),
);
Finder findAppBarMaterial() {
return find.descendant(of: find.byType(AppBar), matching: find.byType(Material));
}
Color? getAppBarBackgroundColor() {
return tester.widget<Material>(findAppBarMaterial()).color;
}
expect(getAppBarBackgroundColor(), defaultColor);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(-100.0, 0.0));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(), defaultColor); expect(tester.takeException(), isNull);
});
gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(100.0, 0.0));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(), defaultColor); testWidgets('does not trigger on horizontal scroll', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
return states.contains(MaterialState.scrolledUnder)
? scrolledColor
: defaultColor;
}),
title: const Text('AppBar'),
),
body: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(height: 600.0, width: 1200.0, color: Colors.teal),
],
),
),
),
);
expect(getAppBarBackgroundColor(tester), defaultColor);
TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(-100.0, 0.0));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(100.0, 0.0));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
});
testWidgets('backgroundColor - not triggered in reverse for short content', (WidgetTester tester) async {
await tester.pumpWidget(
_buildAppBar(
contentHeight: 200.0,
reverse: true,
)
);
await tester.pump();
// In reverse, the content here is not long enough to scroll under the app
// bar.
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
final TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
});
testWidgets('backgroundColor with FlexibleSpace - not triggered in reverse for short content', (WidgetTester tester) async {
await tester.pumpWidget(
_buildAppBar(
contentHeight: 200.0,
reverse: true,
includeFlexibleSpace: true,
)
);
await tester.pump();
// In reverse, the content here is not long enough to scroll under the app
// bar.
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
final TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0));
await gesture.moveBy(const Offset(0.0, kToolbarHeight));
await gesture.up();
await tester.pumpAndSettle();
expect(getAppBarBackgroundColor(tester), defaultColor);
expect(tester.getSize(findAppBarMaterial()).height, kToolbarHeight);
});
});
}); });
testWidgets('AppBar.preferredHeightFor', (WidgetTester tester) async { testWidgets('AppBar.preferredHeightFor', (WidgetTester tester) async {
......
...@@ -349,6 +349,7 @@ void main() { ...@@ -349,6 +349,7 @@ void main() {
' Material\n' ' Material\n'
' _ScrollNotificationObserverScope\n' ' _ScrollNotificationObserverScope\n'
' NotificationListener<ScrollNotification>\n' ' NotificationListener<ScrollNotification>\n'
' NotificationListener<ScrollMetricsNotification>\n'
' ScrollNotificationObserver\n' ' ScrollNotificationObserver\n'
' _ScaffoldScope\n' ' _ScaffoldScope\n'
' Scaffold-[LabeledGlobalKey<ScaffoldState>#00000]\n' ' Scaffold-[LabeledGlobalKey<ScaffoldState>#00000]\n'
......
...@@ -2339,6 +2339,7 @@ void main() { ...@@ -2339,6 +2339,7 @@ void main() {
' Material\n' ' Material\n'
' _ScrollNotificationObserverScope\n' ' _ScrollNotificationObserverScope\n'
' NotificationListener<ScrollNotification>\n' ' NotificationListener<ScrollNotification>\n'
' NotificationListener<ScrollMetricsNotification>\n'
' ScrollNotificationObserver\n' ' ScrollNotificationObserver\n'
' _ScaffoldScope\n' ' _ScaffoldScope\n'
' Scaffold\n' ' Scaffold\n'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment