@@ -1177,4 +1177,69 @@ void main() {
1177
1177
1178
1178
expect (tester.layers, contains (isA <ImageFilterLayer >()));
1179
1179
});
1180
+
1181
+ testWidgets ('Stretching animation completes after fling under scroll physics with high friction' , (WidgetTester tester) async {
1182
+ // Regression test for https://github.com/flutter/flutter/issues/146277
1183
+ final GlobalKey box1Key = GlobalKey ();
1184
+ final GlobalKey box2Key = GlobalKey ();
1185
+ final GlobalKey box3Key = GlobalKey ();
1186
+ late final OverscrollNotification overscrollNotification;
1187
+ final ScrollController controller = ScrollController ();
1188
+ addTearDown (controller.dispose);
1189
+
1190
+ await tester.pumpWidget (NotificationListener <OverscrollNotification >(
1191
+ child: buildTest (
1192
+ box1Key,
1193
+ box2Key,
1194
+ box3Key,
1195
+ controller,
1196
+ physics: const _HighFrictionClampingScrollPhysics (),
1197
+ ),
1198
+ onNotification: (OverscrollNotification notification) {
1199
+ overscrollNotification = notification;
1200
+ return false ;
1201
+ },
1202
+ ));
1203
+
1204
+ expect (find.byType (StretchingOverscrollIndicator ), findsOneWidget);
1205
+ expect (find.byType (GlowingOverscrollIndicator ), findsNothing);
1206
+ final RenderBox box1 = tester.renderObject (find.byKey (box1Key));
1207
+ final RenderBox box2 = tester.renderObject (find.byKey (box2Key));
1208
+ final RenderBox box3 = tester.renderObject (find.byKey (box3Key));
1209
+
1210
+ expect (controller.offset, 0.0 );
1211
+ expect (box1.localToGlobal (Offset .zero), Offset .zero);
1212
+ expect (box2.localToGlobal (Offset .zero), const Offset (0.0 , 250.0 ));
1213
+ expect (box3.localToGlobal (Offset .zero), const Offset (0.0 , 500.0 ));
1214
+
1215
+ // We fling to the trailing edge and let it settle.
1216
+ await tester.fling (find.byType (CustomScrollView ), const Offset (0.0 , - 50.0 ), 10000.0 );
1217
+ await tester.pumpAndSettle ();
1218
+
1219
+ // We are now at the trailing edge
1220
+ expect (overscrollNotification.velocity, lessThan (25 ));
1221
+ expect (controller.offset, 150.0 );
1222
+ expect (box1.localToGlobal (Offset .zero).dy, - 150.0 );
1223
+ expect (box2.localToGlobal (Offset .zero).dy, 100.0 );
1224
+ expect (box3.localToGlobal (Offset .zero).dy, 350.0 );
1225
+ });
1226
+ }
1227
+
1228
+ final class _HighFrictionClampingScrollPhysics extends ScrollPhysics {
1229
+ const _HighFrictionClampingScrollPhysics ({super .parent});
1230
+
1231
+ @override
1232
+ ScrollPhysics applyTo (ScrollPhysics ? ancestor) {
1233
+ return _HighFrictionClampingScrollPhysics (parent: buildParent (ancestor));
1234
+ }
1235
+
1236
+ @override
1237
+ Simulation ? createBallisticSimulation (ScrollMetrics position, double velocity) {
1238
+ return ClampingScrollSimulation (
1239
+ position: position.pixels,
1240
+ velocity: velocity,
1241
+ friction: 0.94 ,
1242
+ tolerance: tolerance,
1243
+ );
1244
+ }
1180
1245
}
0 commit comments