Unverified Commit 1c433997 authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Fix disallowIndicator for RefreshIndicator (#106831)

parent 49a52ae8
......@@ -383,12 +383,12 @@ class RefreshIndicatorState extends State<RefreshIndicator> with TickerProviderS
return false;
}
bool _handleGlowNotification(OverscrollIndicatorNotification notification) {
bool _handleIndicatorNotification(OverscrollIndicatorNotification notification) {
if (notification.depth != 0 || !notification.leading) {
return false;
}
if (_mode == _RefreshIndicatorMode.drag) {
notification.disallowGlow();
notification.disallowIndicator();
return true;
}
return false;
......@@ -535,7 +535,7 @@ class RefreshIndicatorState extends State<RefreshIndicator> with TickerProviderS
final Widget child = NotificationListener<ScrollNotification>(
onNotification: _handleScrollNotification,
child: NotificationListener<OverscrollIndicatorNotification>(
onNotification: _handleGlowNotification,
onNotification: _handleIndicatorNotification,
child: widget.child,
),
);
......
......@@ -234,7 +234,7 @@ class _GlowingOverscrollIndicatorState extends State<GlowingOverscrollIndicator>
if (_lastNotificationType is! OverscrollNotification) {
final OverscrollIndicatorNotification confirmationNotification = OverscrollIndicatorNotification(leading: isLeading);
confirmationNotification.dispatch(context);
_accepted[isLeading] = confirmationNotification._accepted;
_accepted[isLeading] = confirmationNotification.accepted;
if (_accepted[isLeading]!) {
controller!._paintOffset = confirmationNotification.paintOffset;
}
......@@ -714,7 +714,7 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
if (_lastNotification.runtimeType is! OverscrollNotification) {
final OverscrollIndicatorNotification confirmationNotification = OverscrollIndicatorNotification(leading: notification.overscroll < 0.0);
confirmationNotification.dispatch(context);
_accepted = confirmationNotification._accepted;
_accepted = confirmationNotification.accepted;
}
assert(notification.metrics.axis == widget.axis);
......@@ -978,7 +978,16 @@ class OverscrollIndicatorNotification extends Notification with ViewportNotifica
/// This has no effect on a [StretchingOverscrollIndicator].
double paintOffset = 0.0;
bool _accepted = true;
@protected
@visibleForTesting
/// Whether the current overscroll event will allow for the indicator to be
/// shown.
///
/// Calling [disallowIndicator] sets this to false, preventing the over scroll
/// indicator from showing.
///
/// Defaults to true, cannot be null.
bool accepted = true;
/// Call this method if the glow should be prevented. This method is
/// deprecated in favor of [disallowIndicator].
......@@ -987,12 +996,12 @@ class OverscrollIndicatorNotification extends Notification with ViewportNotifica
'This feature was deprecated after v2.5.0-6.0.pre.',
)
void disallowGlow() {
_accepted = false;
accepted = false;
}
/// Call this method if the overscroll indicator should be prevented.
void disallowIndicator() {
_accepted = false;
accepted = false;
}
@override
......
......@@ -902,4 +902,107 @@ void main() {
await tester.pump(const Duration(seconds: 1)); // finish the indicator hide animation
expect(refreshCalled, true);
});
testWidgets('RefreshIndicator disallows indicator - glow', (WidgetTester tester) async {
refreshCalled = false;
bool glowAccepted = true;
ScrollNotification? lastNotification;
await tester.pumpWidget(
MaterialApp(
home: RefreshIndicator(
onRefresh: refresh,
child: Builder(
builder: (BuildContext context) {
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
if (notification is OverscrollNotification
&& lastNotification is! OverscrollNotification) {
final OverscrollIndicatorNotification confirmationNotification = OverscrollIndicatorNotification(leading: true);
confirmationNotification.dispatch(context);
glowAccepted = confirmationNotification.accepted;
}
lastNotification = notification;
return false;
},
child: ListView(
physics: const AlwaysScrollableScrollPhysics(),
children: <String>['A', 'B', 'C', 'D', 'E', 'F'].map<Widget>((String item) {
return SizedBox(
height: 200.0,
child: Text(item),
);
}).toList(),
),
);
}
),
),
),
);
expect(find.byType(StretchingOverscrollIndicator), findsNothing);
expect(find.byType(GlowingOverscrollIndicator), findsOneWidget);
await tester.fling(find.text('A'), const Offset(0.0, 300.0), 1000.0);
await tester.pump();
await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
await tester.pump(const Duration(seconds: 1)); // finish the indicator settle animation
await tester.pump(const Duration(seconds: 1)); // finish the indicator hide animation
expect(refreshCalled, true);
expect(glowAccepted, false);
});
testWidgets('RefreshIndicator disallows indicator - stretch', (WidgetTester tester) async {
refreshCalled = false;
bool stretchAccepted = true;
ScrollNotification? lastNotification;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light().copyWith(useMaterial3: true),
home: RefreshIndicator(
onRefresh: refresh,
child: Builder(
builder: (BuildContext context) {
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
if (notification is OverscrollNotification
&& lastNotification is! OverscrollNotification) {
final OverscrollIndicatorNotification confirmationNotification = OverscrollIndicatorNotification(leading: true);
confirmationNotification.dispatch(context);
stretchAccepted = confirmationNotification.accepted;
}
lastNotification = notification;
return false;
},
child: ListView(
physics: const AlwaysScrollableScrollPhysics(),
children: <String>['A', 'B', 'C', 'D', 'E', 'F'].map<Widget>((String item) {
return SizedBox(
height: 200.0,
child: Text(item),
);
}).toList(),
),
);
}
),
),
),
);
expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
expect(find.byType(GlowingOverscrollIndicator), findsNothing);
await tester.fling(find.text('A'), const Offset(0.0, 300.0), 1000.0);
await tester.pump();
await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
await tester.pump(const Duration(seconds: 1)); // finish the indicator settle animation
await tester.pump(const Duration(seconds: 1)); // finish the indicator hide animation
expect(refreshCalled, true);
expect(stretchAccepted, false);
});
}
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