Skip to content

Commit a3dd5ae

Browse files
authored
ScrollController.jumpTo zero should not trigger the refresh indicator (flutter#75764)
1 parent fe0ceeb commit a3dd5ae

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

packages/flutter/lib/src/material/refresh_indicator.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,11 @@ class RefreshIndicatorState extends State<RefreshIndicator> with TickerProviderS
262262
}
263263

264264
bool _shouldStart(ScrollNotification notification) {
265-
return (notification is ScrollStartNotification || (notification is ScrollUpdateNotification && notification.dragDetails != null && widget.triggerMode == RefreshIndicatorTriggerMode.anywhere))
265+
// If the notification.dragDetails is null, this scroll is not triggered by
266+
// user dragging. It may be a result of ScrollController.jumpTo or ballistic scroll.
267+
// In this case, we don't want to trigger the refresh indicator.
268+
return ((notification is ScrollStartNotification && notification.dragDetails != null)
269+
|| (notification is ScrollUpdateNotification && notification.dragDetails != null && widget.triggerMode == RefreshIndicatorTriggerMode.anywhere))
266270
&& notification.metrics.extentBefore == 0.0
267271
&& _mode == null
268272
&& _start(notification.metrics.axisDirection);

packages/flutter/test/material/refresh_indicator_test.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,38 @@ void main() {
677677
expect(find.byType(RefreshProgressIndicator), findsNothing);
678678
});
679679

680+
testWidgets('ScrollController.jumpTo should not trigger the refresh indicator', (WidgetTester tester) async {
681+
refreshCalled = false;
682+
final ScrollController scrollController = ScrollController(initialScrollOffset: 500.0);
683+
await tester.pumpWidget(
684+
MaterialApp(
685+
home: RefreshIndicator(
686+
onRefresh: refresh,
687+
child: ListView(
688+
controller: scrollController,
689+
physics: const AlwaysScrollableScrollPhysics(),
690+
children: const <Widget>[
691+
SizedBox(
692+
height: 800.0,
693+
child: Text('X'),
694+
),
695+
SizedBox(
696+
height: 800.0,
697+
child: Text('Y'),
698+
),
699+
],
700+
),
701+
),
702+
),
703+
);
704+
705+
scrollController.jumpTo(0.0);
706+
await tester.pump(const Duration(seconds: 1)); // finish the indicator settle animation
707+
await tester.pump(const Duration(seconds: 1)); // finish the indicator hide animation
708+
709+
expect(refreshCalled, false);
710+
});
711+
680712
testWidgets('RefreshIndicator.color can be updated at runtime', (WidgetTester tester) async {
681713
refreshCalled = false;
682714
Color refreshIndicatorColor = Colors.green;

0 commit comments

Comments
 (0)