Revert "Added MaterialState.scrolledUnder and support in AppBar.backgroundColor (#79999)" (#80380)
This reverts commit 17870d5d7eb81bc2021454093e9115c2c0d3c850.
diff --git a/packages/flutter/lib/src/material/app_bar.dart b/packages/flutter/lib/src/material/app_bar.dart
index 78678e5..1397c6e 100644
--- a/packages/flutter/lib/src/material/app_bar.dart
+++ b/packages/flutter/lib/src/material/app_bar.dart
@@ -19,7 +19,6 @@
import 'icons.dart';
import 'material.dart';
import 'material_localizations.dart';
-import 'material_state.dart';
import 'scaffold.dart';
import 'tabs.dart';
import 'text_theme.dart';
@@ -703,28 +702,6 @@
static const double _defaultElevation = 4.0;
static const Color _defaultShadowColor = Color(0xFF000000);
- ScrollNotificationObserverState? _scrollNotificationObserver;
- bool _scrolledUnder = false;
-
- @override
- void didChangeDependencies() {
- super.didChangeDependencies();
- if (_scrollNotificationObserver != null)
- _scrollNotificationObserver!.removeListener(_handleScrollNotification);
- _scrollNotificationObserver = ScrollNotificationObserver.of(context);
- if (_scrollNotificationObserver != null)
- _scrollNotificationObserver!.addListener(_handleScrollNotification);
- }
-
- @override
- void dispose() {
- if (_scrollNotificationObserver != null) {
- _scrollNotificationObserver!.removeListener(_handleScrollNotification);
- _scrollNotificationObserver = null;
- }
- super.dispose();
- }
-
void _handleDrawerButton() {
Scaffold.of(context).openDrawer();
}
@@ -733,22 +710,6 @@
Scaffold.of(context).openEndDrawer();
}
- void _handleScrollNotification(ScrollNotification notification) {
- final bool oldScrolledUnder = _scrolledUnder;
- _scrolledUnder = notification.depth == 0 && notification.metrics.extentBefore > 0;
- if (_scrolledUnder != oldScrolledUnder) {
- setState(() {
- // React to a change in MaterialState.scrolledUnder
- });
- }
- }
-
- Color _resolveColor(Set<MaterialState> states, Color? widgetColor, Color? themeColor, Color defaultColor) {
- return MaterialStateProperty.resolveAs<Color?>(widgetColor, states)
- ?? MaterialStateProperty.resolveAs<Color?>(themeColor, states)
- ?? MaterialStateProperty.resolveAs<Color>(defaultColor, states);
- }
-
@override
Widget build(BuildContext context) {
assert(!widget.primary || debugCheckHasMediaQuery(context));
@@ -759,11 +720,6 @@
final ScaffoldState? scaffold = Scaffold.maybeOf(context);
final ModalRoute<dynamic>? parentRoute = ModalRoute.of(context);
- final FlexibleSpaceBarSettings? settings = context.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
- final Set<MaterialState> states = <MaterialState>{
- if (settings?.isScrolledUnder ?? _scrolledUnder) MaterialState.scrolledUnder,
- };
-
final bool hasDrawer = scaffold?.hasDrawer ?? false;
final bool hasEndDrawer = scaffold?.hasEndDrawer ?? false;
final bool canPop = parentRoute?.canPop ?? false;
@@ -776,11 +732,9 @@
? widget.backgroundColor
?? appBarTheme.backgroundColor
?? theme.primaryColor
- : _resolveColor(
- states,
- widget.backgroundColor,
- appBarTheme.backgroundColor,
- colorScheme.brightness == Brightness.dark ? colorScheme.surface : colorScheme.primary);
+ : widget.backgroundColor
+ ?? appBarTheme.backgroundColor
+ ?? (colorScheme.brightness == Brightness.dark ? colorScheme.surface : colorScheme.primary);
final Color foregroundColor = widget.foregroundColor
?? appBarTheme.foregroundColor
@@ -1182,7 +1136,6 @@
final double extraToolbarHeight = math.max(minExtent - _bottomHeight - topPadding - (toolbarHeight ?? kToolbarHeight), 0.0);
final double visibleToolbarHeight = visibleMainHeight - _bottomHeight - extraToolbarHeight;
- final bool isScrolledUnder = overlapsContent || (pinned && shrinkOffset > maxExtent - minExtent);
final bool isPinnedWithOpacityFade = pinned && floating && bottom != null && extraToolbarHeight == 0.0;
final double toolbarOpacity = !pinned || isPinnedWithOpacityFade
? (visibleToolbarHeight / (toolbarHeight ?? kToolbarHeight)).clamp(0.0, 1.0)
@@ -1193,7 +1146,6 @@
maxExtent: maxExtent,
currentExtent: math.max(minExtent, maxExtent - shrinkOffset),
toolbarOpacity: toolbarOpacity,
- isScrolledUnder: isScrolledUnder,
child: AppBar(
leading: leading,
automaticallyImplyLeading: automaticallyImplyLeading,
@@ -1203,7 +1155,7 @@
? Semantics(child: flexibleSpace, header: true)
: flexibleSpace,
bottom: bottom,
- elevation: forceElevated || isScrolledUnder ? elevation : 0.0,
+ elevation: forceElevated || overlapsContent || (pinned && shrinkOffset > maxExtent - minExtent) ? elevation : 0.0,
shadowColor: shadowColor,
backgroundColor: backgroundColor,
foregroundColor: foregroundColor,
@@ -1562,10 +1514,6 @@
/// {@macro flutter.material.appbar.backgroundColor}
///
/// This property is used to configure an [AppBar].
- ///
- /// If this color is a [MaterialStateColor] it will be resolved against
- /// [MaterialState.scrolledUnder] when the content of the app's
- /// primary scrollable overlaps the app bar.
final Color? backgroundColor;
/// {@macro flutter.material.appbar.foregroundColor}
diff --git a/packages/flutter/lib/src/material/flexible_space_bar.dart b/packages/flutter/lib/src/material/flexible_space_bar.dart
index 7f45145..5dffe23 100644
--- a/packages/flutter/lib/src/material/flexible_space_bar.dart
+++ b/packages/flutter/lib/src/material/flexible_space_bar.dart
@@ -210,9 +210,8 @@
/// height of the resulting [FlexibleSpaceBar] when fully expanded.
/// `currentExtent` sets the scale of the [FlexibleSpaceBar.background] and
/// [FlexibleSpaceBar.title] widgets of [FlexibleSpaceBar] upon
- /// initialization. `scrolledUnder` is true if the the [FlexibleSpaceBar]
- /// overlaps the app's primary scrollable, false if it does not, and null
- /// if the caller has not determined as much.
+ /// initialization.
+ ///
/// See also:
///
/// * [FlexibleSpaceBarSettings] which creates a settings object that can be
@@ -221,7 +220,6 @@
double? toolbarOpacity,
double? minExtent,
double? maxExtent,
- bool? isScrolledUnder,
required double currentExtent,
required Widget child,
}) {
@@ -230,7 +228,6 @@
toolbarOpacity: toolbarOpacity ?? 1.0,
minExtent: minExtent ?? currentExtent,
maxExtent: maxExtent ?? currentExtent,
- isScrolledUnder: isScrolledUnder,
currentExtent: currentExtent,
child: child,
);
@@ -444,7 +441,6 @@
required this.maxExtent,
required this.currentExtent,
required Widget child,
- this.isScrolledUnder,
}) : assert(toolbarOpacity != null),
assert(minExtent != null && minExtent >= 0),
assert(maxExtent != null && maxExtent >= 0),
@@ -469,23 +465,11 @@
/// these elements upon initialization.
final double currentExtent;
- /// True if the FlexibleSpaceBar overlaps the primary scrollable's contents.
- ///
- /// This value is used by the [AppBar] to resolve
- /// [AppBar.backgroundColor] against [MaterialState.scrolledUnder],
- /// i.e. to enable apps to specify different colors when content
- /// has been scrolled up and behind the app bar.
- ///
- /// Null if the caller hasn't determined if the FlexibleSpaceBar
- /// overlaps the primary scrollable's contents.
- final bool? isScrolledUnder;
-
@override
bool updateShouldNotify(FlexibleSpaceBarSettings oldWidget) {
return toolbarOpacity != oldWidget.toolbarOpacity
|| minExtent != oldWidget.minExtent
|| maxExtent != oldWidget.maxExtent
- || currentExtent != oldWidget.currentExtent
- || isScrolledUnder != oldWidget.isScrolledUnder;
+ || currentExtent != oldWidget.currentExtent;
}
}
diff --git a/packages/flutter/lib/src/material/material_state.dart b/packages/flutter/lib/src/material/material_state.dart
index b4808bb..73c661d 100644
--- a/packages/flutter/lib/src/material/material_state.dart
+++ b/packages/flutter/lib/src/material/material_state.dart
@@ -63,13 +63,7 @@
/// See: https://material.io/design/interaction/states.html#selected.
selected,
- /// The state when this widget overlaps the content of a scrollable below.
- ///
- /// Used by [AppBar] to indicate that the primary scrollable's
- /// content has scrolled up and behind the app bar.
- scrolledUnder,
-
- /// The state when this widget is disabled and cannot be interacted with.
+ /// The state when this widget disabled and can not be interacted with.
///
/// Disabled widgets should not respond to hover, focus, press, or drag
/// interactions.
diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart
index c142a92..e229694 100644
--- a/packages/flutter/lib/src/material/scaffold.dart
+++ b/packages/flutter/lib/src/material/scaffold.dart
@@ -3238,29 +3238,27 @@
return _ScaffoldScope(
hasDrawer: hasDrawer,
geometryNotifier: _geometryNotifier,
- child: ScrollNotificationObserver(
- child: Material(
- color: widget.backgroundColor ?? themeData.scaffoldBackgroundColor,
- child: AnimatedBuilder(animation: _floatingActionButtonMoveController, builder: (BuildContext context, Widget? child) {
- return CustomMultiChildLayout(
- children: children,
- delegate: _ScaffoldLayout(
- extendBody: _extendBody,
- extendBodyBehindAppBar: widget.extendBodyBehindAppBar,
- minInsets: minInsets,
- minViewPadding: minViewPadding,
- currentFloatingActionButtonLocation: _floatingActionButtonLocation!,
- floatingActionButtonMoveAnimationProgress: _floatingActionButtonMoveController.value,
- floatingActionButtonMotionAnimator: _floatingActionButtonAnimator,
- geometryNotifier: _geometryNotifier,
- previousFloatingActionButtonLocation: _previousFloatingActionButtonLocation!,
- textDirection: textDirection,
- isSnackBarFloating: isSnackBarFloating,
- snackBarWidth: snackBarWidth,
- ),
- );
- }),
- ),
+ child: Material(
+ color: widget.backgroundColor ?? themeData.scaffoldBackgroundColor,
+ child: AnimatedBuilder(animation: _floatingActionButtonMoveController, builder: (BuildContext context, Widget? child) {
+ return CustomMultiChildLayout(
+ children: children,
+ delegate: _ScaffoldLayout(
+ extendBody: _extendBody,
+ extendBodyBehindAppBar: widget.extendBodyBehindAppBar,
+ minInsets: minInsets,
+ minViewPadding: minViewPadding,
+ currentFloatingActionButtonLocation: _floatingActionButtonLocation!,
+ floatingActionButtonMoveAnimationProgress: _floatingActionButtonMoveController.value,
+ floatingActionButtonMotionAnimator: _floatingActionButtonAnimator,
+ geometryNotifier: _geometryNotifier,
+ previousFloatingActionButtonLocation: _previousFloatingActionButtonLocation!,
+ textDirection: textDirection,
+ isSnackBarFloating: isSnackBarFloating,
+ snackBarWidth: snackBarWidth,
+ ),
+ );
+ }),
),
);
}
diff --git a/packages/flutter/lib/src/widgets/scroll_notification_observer.dart b/packages/flutter/lib/src/widgets/scroll_notification_observer.dart
deleted file mode 100644
index e2dd909..0000000
--- a/packages/flutter/lib/src/widgets/scroll_notification_observer.dart
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:flutter/foundation.dart';
-
-import 'framework.dart';
-import 'notification_listener.dart';
-import 'scroll_notification.dart';
-
-/// A [ScrollNotification] listener for [ScrollNotificationObserver].
-///
-/// [ScrollNotificationObserver] is similar to
-/// [NotificationListener]. It supports a listener list instead of
-/// just a single listener and its listeners run unconditionally, they
-/// do not require a gating boolean return value.
-typedef ScrollNotificationCallback = void Function(ScrollNotification notification);
-
-class _ScrollNotificationObserverScope extends InheritedWidget {
- const _ScrollNotificationObserverScope({
- Key? key,
- required Widget child,
- required ScrollNotificationObserverState scrollNotificationObserverState,
- }) : _scrollNotificationObserverState = scrollNotificationObserverState,
- super(key: key, child: child);
-
- final ScrollNotificationObserverState _scrollNotificationObserverState;
-
- @override
- bool updateShouldNotify(_ScrollNotificationObserverScope old) => _scrollNotificationObserverState != old._scrollNotificationObserverState;
-}
-
-class _ListenerEntry extends LinkedListEntry<_ListenerEntry> {
- _ListenerEntry(this.listener);
- final ScrollNotificationCallback listener;
-}
-
-/// Notifies its listeners when a descendant scrolls.
-///
-/// To add a listener to a [ScrollNotificationObserver] ancestor:
-/// ```dart
-/// void listener(ScrollNotification notification) {
-/// // Do something, maybe setState()
-/// }
-/// ScrollNotificationObserver.of(context).addListener(listener)
-/// ```
-///
-/// To remove the listener from a [ScrollNotificationObserver] ancestor:
-/// ```dart
-/// ScrollNotificationObserver.of(context).removeListener(listener);
-///```
-///
-/// Stateful widgets that share an ancestor [ScrollNotificationObserver] typically
-/// add a listener in [State.didChangeDependencies] (removing the old one
-/// if necessary) and remove the listener in their [State.dispose] method.
-///
-/// This widget is similar to [NotificationListener]. It supports
-/// a listener list instead of just a single listener and its listeners
-/// run unconditionally, they do not require a gating boolean return value.
-class ScrollNotificationObserver extends StatefulWidget {
- /// Create a [ScrollNotificationObserver].
- ///
- /// The [child] parameter must not be null.
- const ScrollNotificationObserver({
- Key? key,
- required this.child,
- }) : assert(child != null), super(key: key);
-
- /// The subtree below this widget.
- final Widget child;
-
- /// The closest instance of this class that encloses the given context.
- ///
- /// If there is no enclosing [ScrollNotificationObserver] widget, then null is returned.
- static ScrollNotificationObserverState? of(BuildContext context) {
- return context.dependOnInheritedWidgetOfExactType<_ScrollNotificationObserverScope>()?._scrollNotificationObserverState;
- }
-
- @override
- ScrollNotificationObserverState createState() => ScrollNotificationObserverState();
-}
-
-/// The listener list state for a [ScrollNotificationObserver] returned by
-/// [ScrollNotificationObserver.of].
-///
-/// [ScrollNotificationObserver] is similar to
-/// [NotificationListener]. It supports a listener list instead of
-/// just a single listener and its listeners run unconditionally, they
-/// do not require a gating boolean return value.
-class ScrollNotificationObserverState extends State<ScrollNotificationObserver> {
- LinkedList<_ListenerEntry>? _listeners = LinkedList<_ListenerEntry>();
-
- bool _debugAssertNotDisposed() {
- assert(() {
- if (_listeners == null) {
- throw FlutterError(
- 'A $runtimeType was used after being disposed.\n'
- 'Once you have called dispose() on a $runtimeType, it can no longer be used.',
- );
- }
- return true;
- }());
- return true;
- }
-
- /// Add a [ScrollNotificationCallback] that will be called each time
- /// a descendant scrolls.
- void addListener(ScrollNotificationCallback listener) {
- assert(_debugAssertNotDisposed());
- _listeners!.add(_ListenerEntry(listener));
- }
-
- /// Remove the specified [ScrollNotificationCallback].
- void removeListener(ScrollNotificationCallback listener) {
- assert(_debugAssertNotDisposed());
- for (final _ListenerEntry entry in _listeners!) {
- if (entry.listener == listener) {
- entry.unlink();
- return;
- }
- }
- }
-
- void _notifyListeners(ScrollNotification notification) {
- assert(_debugAssertNotDisposed());
- if (_listeners!.isEmpty)
- return;
-
- final List<_ListenerEntry> localListeners = List<_ListenerEntry>.from(_listeners!);
- for (final _ListenerEntry entry in localListeners) {
- try {
- if (entry.list != null)
- entry.listener(notification);
- } catch (exception, stack) {
- FlutterError.reportError(FlutterErrorDetails(
- exception: exception,
- stack: stack,
- library: 'widget library',
- context: ErrorDescription('while dispatching notifications for $runtimeType'),
- informationCollector: () sync* {
- yield DiagnosticsProperty<ScrollNotificationObserverState>(
- 'The $runtimeType sending notification was',
- this,
- style: DiagnosticsTreeStyle.errorProperty,
- );
- },
- ));
- }
- }
- }
-
- @override
- Widget build(BuildContext context) {
- return NotificationListener<ScrollNotification>(
- onNotification: (ScrollNotification notification) {
- _notifyListeners(notification);
- return false;
- },
- child: _ScrollNotificationObserverScope(
- scrollNotificationObserverState: this,
- child: widget.child,
- ),
- );
- }
-
- @override
- void dispose() {
- assert(_debugAssertNotDisposed());
- _listeners = null;
- super.dispose();
- }
-}
diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart
index 9e02df98..48716c7 100644
--- a/packages/flutter/lib/widgets.dart
+++ b/packages/flutter/lib/widgets.dart
@@ -98,7 +98,6 @@
export 'src/widgets/scroll_controller.dart';
export 'src/widgets/scroll_metrics.dart';
export 'src/widgets/scroll_notification.dart';
-export 'src/widgets/scroll_notification_observer.dart';
export 'src/widgets/scroll_physics.dart';
export 'src/widgets/scroll_position.dart';
export 'src/widgets/scroll_position_with_single_context.dart';
diff --git a/packages/flutter/test/material/app_bar_test.dart b/packages/flutter/test/material/app_bar_test.dart
index ee00a99..d54a4ea 100644
--- a/packages/flutter/test/material/app_bar_test.dart
+++ b/packages/flutter/test/material/app_bar_test.dart
@@ -2518,239 +2518,4 @@
expect(actionIconTheme.color, foregroundColor);
});
- testWidgets('SliverAppBar.backgroundColor MaterialStateColor scrolledUnder', (WidgetTester tester) async {
- const double collapsedHeight = kToolbarHeight;
- const double expandedHeight = 200.0;
- const Color scrolledColor = Color(0xff00ff00);
- const Color defaultColor = Color(0xff0000ff);
-
- await tester.pumpWidget(
- MaterialApp(
- home: Scaffold(
- body: CustomScrollView(
- slivers: <Widget>[
- SliverAppBar(
- backwardsCompatibility: false,
- 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() {
- 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, 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('SliverAppBar.backgroundColor with FlexibleSpace MaterialStateColor scrolledUnder', (WidgetTester tester) async {
- const double collapsedHeight = kToolbarHeight;
- const double expandedHeight = 200.0;
- const Color scrolledColor = Color(0xff00ff00);
- const Color defaultColor = Color(0xff0000ff);
-
- await tester.pumpWidget(
- MaterialApp(
- home: Scaffold(
- body: CustomScrollView(
- slivers: <Widget>[
- SliverAppBar(
- backwardsCompatibility: false,
- 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(
- delegate: SliverChildListDelegate(
- <Widget>[
- Container(height: 1200.0, 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(
- backwardsCompatibility: false,
- 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(
- backwardsCompatibility: false,
- 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),
- ],
- ),
- ),
- ),
- );
-
- 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, 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);
- });
}
diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart
index f868339..4f2b0a1 100644
--- a/packages/flutter/test/material/scaffold_test.dart
+++ b/packages/flutter/test/material/scaffold_test.dart
@@ -2190,9 +2190,6 @@
' PhysicalModel\n'
' AnimatedPhysicalModel\n'
' Material\n'
- ' _ScrollNotificationObserverScope\n'
- ' NotificationListener<ScrollNotification>\n'
- ' ScrollNotificationObserver\n'
' _ScaffoldScope\n'
' Scaffold\n'
' MediaQuery\n'
diff --git a/packages/flutter/test/widgets/scroll_notification_test.dart b/packages/flutter/test/widgets/scroll_notification_test.dart
index f85eda9..20d7077 100644
--- a/packages/flutter/test/widgets/scroll_notification_test.dart
+++ b/packages/flutter/test/widgets/scroll_notification_test.dart
@@ -150,69 +150,4 @@
expect(notificationTypes, equals(types));
});
- testWidgets('ScrollNotificationObserver', (WidgetTester tester) async {
- late ScrollNotificationObserverState observer;
- ScrollNotification? notification;
-
- void handleNotification(ScrollNotification value) {
- if (value is ScrollStartNotification || value is ScrollUpdateNotification || value is ScrollEndNotification)
- notification = value;
- }
-
- await tester.pumpWidget(
- ScrollNotificationObserver(
- child: Builder(
- builder: (BuildContext context) {
- observer = ScrollNotificationObserver.of(context)!;
- return const SingleChildScrollView(
- child: SizedBox(height: 1200.0),
- );
- },
- ),
- ),
- );
-
- observer.addListener(handleNotification);
-
- TestGesture gesture = await tester.startGesture(const Offset(100.0, 100.0));
- await tester.pumpAndSettle();
- expect(notification, isA<ScrollStartNotification>());
- expect(notification!.depth, equals(0));
-
- final ScrollStartNotification start = notification! as ScrollStartNotification;
- expect(start.dragDetails, isNotNull);
- expect(start.dragDetails!.globalPosition, equals(const Offset(100.0, 100.0)));
-
- await gesture.moveBy(const Offset(-10.0, -10.0));
- await tester.pumpAndSettle();
- expect(notification, isA<ScrollUpdateNotification>());
- expect(notification!.depth, equals(0));
- final ScrollUpdateNotification update = notification! as ScrollUpdateNotification;
- expect(update.dragDetails, isNotNull);
- expect(update.dragDetails!.globalPosition, equals(const Offset(90.0, 90.0)));
- expect(update.dragDetails!.delta, equals(const Offset(0.0, -10.0)));
-
- await gesture.up();
- await tester.pumpAndSettle();
- expect(notification, isA<ScrollEndNotification>());
- expect(notification!.depth, equals(0));
- final ScrollEndNotification end = notification! as ScrollEndNotification;
- expect(end.dragDetails, isNotNull);
- expect(end.dragDetails!.velocity, equals(Velocity.zero));
-
- observer.removeListener(handleNotification);
- notification = null;
-
- gesture = await tester.startGesture(const Offset(100.0, 100.0));
- await tester.pumpAndSettle();
- expect(notification, isNull);
-
- await gesture.moveBy(const Offset(-10.0, -10.0));
- await tester.pumpAndSettle();
- expect(notification, isNull);
-
- await gesture.up();
- await tester.pumpAndSettle();
- expect(notification, isNull);
- });
}