Commit f021ee27 authored by vanya elizarov's avatar vanya elizarov Committed by xster

CupertinoSliverRefreshControl inactive overscroll behavior (#27588)

parent 58939b70
...@@ -520,7 +520,7 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo ...@@ -520,7 +520,7 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo
builder: (BuildContext context, BoxConstraints constraints) { builder: (BuildContext context, BoxConstraints constraints) {
latestIndicatorBoxExtent = constraints.maxHeight; latestIndicatorBoxExtent = constraints.maxHeight;
refreshState = transitionNextState(); refreshState = transitionNextState();
if (widget.builder != null && refreshState != RefreshIndicatorMode.inactive) { if (widget.builder != null && latestIndicatorBoxExtent > 0) {
return widget.builder( return widget.builder(
context, context,
refreshState, refreshState,
......
...@@ -38,16 +38,9 @@ void main() { ...@@ -38,16 +38,9 @@ void main() {
when(mockHelper.builder( when(mockHelper.builder(
any, any, any, any, any)) any, any, any, any, any))
.thenAnswer((Invocation i) { .thenAnswer((Invocation i) {
final RefreshIndicatorMode refreshState = i.positionalArguments[1];
final double pulledExtent = i.positionalArguments[2]; final double pulledExtent = i.positionalArguments[2];
final double refreshTriggerPullDistance = i.positionalArguments[3]; final double refreshTriggerPullDistance = i.positionalArguments[3];
final double refreshIndicatorExtent = i.positionalArguments[4]; final double refreshIndicatorExtent = i.positionalArguments[4];
if (refreshState == RefreshIndicatorMode.inactive) {
throw TestFailure(
'RefreshControlIndicatorBuilder should never be called with the '
"inactive state because there's nothing to build in that case"
);
}
if (pulledExtent < 0.0) { if (pulledExtent < 0.0) {
throw TestFailure('The pulledExtent should never be less than 0.0'); throw TestFailure('The pulledExtent should never be less than 0.0');
} }
...@@ -535,6 +528,94 @@ void main() { ...@@ -535,6 +528,94 @@ void main() {
debugDefaultTargetPlatformOverride = null; debugDefaultTargetPlatformOverride = null;
}); });
testWidgets('builder still called when sliver snapped back more than 90%', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
refreshIndicator = const Center(child: Text('-1'));
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));
await tester.pump();
verify(mockHelper.builder(
any,
RefreshIndicatorMode.armed,
150.0,
100.0, // Default value.
60.0, // Default value.
));
expect(
tester.getRect(find.widgetWithText(Center, '-1')),
Rect.fromLTRB(0.0, 0.0, 800.0, 150.0),
);
verify(mockHelper.refreshTask());
// Rebuilds the sliver with a layout extent now.
await tester.pump();
// Let it snap back to occupy the indicator's final sliver space only.
await tester.pump(const Duration(seconds: 2));
verify(mockHelper.builder(
any,
RefreshIndicatorMode.refresh,
60.0,
100.0, // Default value.
60.0, // Default value.
));
expect(
tester.getRect(find.widgetWithText(Center, '-1')),
Rect.fromLTRB(0.0, 0.0, 800.0, 60.0),
);
expect(
tester.getRect(find.widgetWithText(Center, '0')),
Rect.fromLTRB(0.0, 60.0, 800.0, 260.0),
);
refreshCompleter.complete(null);
await tester.pump();
verify(mockHelper.builder(
any,
RefreshIndicatorMode.done,
60.0,
100.0, // Default value.
60.0, // Default value.
));
// Waiting for refresh control to reach approximately 5% of height
await tester.pump(const Duration(milliseconds: 400));
expect(
tester.getRect(find.widgetWithText(Center, '0')).top,
moreOrLessEquals(3.0, epsilon: 4e-1),
);
expect(
tester.getRect(find.widgetWithText(Center, '-1')).height,
moreOrLessEquals(3.0, epsilon: 4e-1),
);
verify(mockHelper.builder(
any,
RefreshIndicatorMode.inactive,
2.6980688300546443, // ~5% of 60.0
100.0, // Default value.
60.0, // Default value.
));
expect(find.text('-1'), findsOneWidget);
debugDefaultTargetPlatformOverride = null;
});
testWidgets( testWidgets(
'retracting sliver during done cannot be pulled to refresh again until fully retracted', 'retracting sliver during done cannot be pulled to refresh again until fully retracted',
(WidgetTester tester) async { (WidgetTester tester) async {
......
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