Fix CupertinoSliverRefreshControl onRefresh callback (#32086)
Replace CupertinoSliverRefreshControl.onRefresh's then callback with whenCompleted callback, so when onRefresh completes with error the sliver refresh control retracts like when it completes with value.
This commit is contained in:
parent
2f75005a16
commit
8800153468
@ -463,7 +463,7 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo
|
||||
// user supplied and we're always here in the middle of the sliver's
|
||||
// performLayout.
|
||||
SchedulerBinding.instance.addPostFrameCallback((Duration timestamp) {
|
||||
refreshTask = widget.onRefresh()..then((_) {
|
||||
refreshTask = widget.onRefresh()..whenComplete(() {
|
||||
if (mounted) {
|
||||
setState(() => refreshTask = null);
|
||||
// Trigger one more transition because by this time, BoxConstraint's
|
||||
|
@ -29,7 +29,7 @@ void main() {
|
||||
double refreshIndicatorExtent,
|
||||
) => mockHelper.builder(context, refreshState, pulledExtent, refreshTriggerPullDistance, refreshIndicatorExtent);
|
||||
|
||||
final Function onRefresh = () => mockHelper.refreshTask();
|
||||
Future<void> onRefresh() => mockHelper.refreshTask();
|
||||
|
||||
setUp(() {
|
||||
mockHelper = MockHelper();
|
||||
@ -52,6 +52,7 @@ void main() {
|
||||
}
|
||||
return refreshIndicator;
|
||||
});
|
||||
|
||||
when(mockHelper.refreshTask()).thenAnswer((_) => refreshCompleter.future);
|
||||
});
|
||||
|
||||
@ -373,6 +374,95 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'refreshing task keeps the sliver expanded forever until completes with error',
|
||||
(WidgetTester tester) async {
|
||||
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
||||
final FlutterError error = FlutterError('Oops');
|
||||
double errorCount = 0;
|
||||
|
||||
runZoned(() async {
|
||||
refreshCompleter = Completer<void>.sync();
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
CupertinoSliverRefreshControl(
|
||||
builder: builder,
|
||||
onRefresh: onRefresh,
|
||||
),
|
||||
buildAListOfStuff(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.drag(find.text('0'), const Offset(0.0, 150.0), touchSlopY: 0);
|
||||
await tester.pump();
|
||||
// Let it start snapping back.
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
|
||||
verifyInOrder(<void>[
|
||||
mockHelper.builder(
|
||||
any,
|
||||
RefreshIndicatorMode.armed,
|
||||
150.0,
|
||||
100.0, // Default value.
|
||||
60.0, // Default value.
|
||||
),
|
||||
mockHelper.refreshTask(),
|
||||
mockHelper.builder(
|
||||
any,
|
||||
RefreshIndicatorMode.armed,
|
||||
argThat(moreOrLessEquals(127.10396988577114)),
|
||||
100.0, // Default value.
|
||||
60.0, // Default value.
|
||||
),
|
||||
]);
|
||||
|
||||
// Reaches refresh state and sliver's at 60.0 in height after a while.
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
verify(mockHelper.builder(
|
||||
any,
|
||||
RefreshIndicatorMode.refresh,
|
||||
60.0,
|
||||
100.0, // Default value.
|
||||
60.0, // Default value.
|
||||
));
|
||||
|
||||
// Stays in that state forever until future completes.
|
||||
await tester.pump(const Duration(seconds: 1000));
|
||||
verifyNoMoreInteractions(mockHelper);
|
||||
expect(
|
||||
tester.getTopLeft(find.widgetWithText(Container, '0')),
|
||||
const Offset(0.0, 60.0),
|
||||
);
|
||||
|
||||
refreshCompleter.completeError(error);
|
||||
await tester.pump();
|
||||
|
||||
verify(mockHelper.builder(
|
||||
any,
|
||||
RefreshIndicatorMode.done,
|
||||
60.0,
|
||||
100.0, // Default value.
|
||||
60.0, // Default value.
|
||||
));
|
||||
verifyNoMoreInteractions(mockHelper);
|
||||
},
|
||||
onError: (dynamic e) {
|
||||
expect(e, error);
|
||||
expect(errorCount, 0);
|
||||
errorCount++;
|
||||
}
|
||||
);
|
||||
|
||||
debugDefaultTargetPlatformOverride = null;
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('expanded refreshing sliver scrolls normally', (WidgetTester tester) async {
|
||||
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user