@@ -451,4 +451,125 @@ void main() {
451451 await gesture.up ();
452452 await tester.pumpAndSettle ();
453453 });
454+
455+ testWidgets ('Stretch limit' , (WidgetTester tester) async {
456+ // Regression test for https://github.com/flutter/flutter/issues/99264
457+ await tester.pumpWidget (
458+ Directionality (
459+ textDirection: TextDirection .ltr,
460+ child: MediaQuery (
461+ data: const MediaQueryData (),
462+ child: ScrollConfiguration (
463+ behavior: const ScrollBehavior ().copyWith (overscroll: false ),
464+ child: StretchingOverscrollIndicator (
465+ axisDirection: AxisDirection .down,
466+ child: SizedBox (
467+ height: 300 ,
468+ child: ListView .builder (
469+ itemCount: 20 ,
470+ itemBuilder: (BuildContext context, int index){
471+ return Padding (
472+ padding: const EdgeInsets .all (10.0 ),
473+ child: Text ('Index $index ' ),
474+ );
475+ },
476+ ),
477+ ),
478+ ),
479+ ),
480+ )
481+ )
482+ );
483+ const double maxStretchLocation = 52.63178407049861 ;
484+
485+ expect (find.text ('Index 1' ), findsOneWidget);
486+ expect (tester.getCenter (find.text ('Index 1' )).dy, 51.0 );
487+
488+ TestGesture pointer = await tester.startGesture (tester.getCenter (find.text ('Index 1' )));
489+ // Overscroll beyond the limit (the viewport is 600.0).
490+ await pointer.moveBy (const Offset (0.0 , 610.0 ));
491+ await tester.pumpAndSettle ();
492+ expect (find.text ('Index 1' ), findsOneWidget);
493+ expect (tester.getCenter (find.text ('Index 1' )).dy, maxStretchLocation);
494+
495+ pointer = await tester.startGesture (tester.getCenter (find.text ('Index 1' )));
496+ // Overscroll way way beyond the limit
497+ await pointer.moveBy (const Offset (0.0 , 1000.0 ));
498+ await tester.pumpAndSettle ();
499+ expect (find.text ('Index 1' ), findsOneWidget);
500+ expect (tester.getCenter (find.text ('Index 1' )).dy, maxStretchLocation);
501+
502+ await pointer.up ();
503+ await tester.pumpAndSettle ();
504+ });
505+
506+ testWidgets ('Multiple pointers wll not exceed stretch limit' , (WidgetTester tester) async {
507+ // Regression test for https://github.com/flutter/flutter/issues/99264
508+ await tester.pumpWidget (
509+ Directionality (
510+ textDirection: TextDirection .ltr,
511+ child: MediaQuery (
512+ data: const MediaQueryData (),
513+ child: ScrollConfiguration (
514+ behavior: const ScrollBehavior ().copyWith (overscroll: false ),
515+ child: StretchingOverscrollIndicator (
516+ axisDirection: AxisDirection .down,
517+ child: SizedBox (
518+ height: 300 ,
519+ child: ListView .builder (
520+ itemCount: 20 ,
521+ itemBuilder: (BuildContext context, int index){
522+ return Padding (
523+ padding: const EdgeInsets .all (10.0 ),
524+ child: Text ('Index $index ' ),
525+ );
526+ },
527+ ),
528+ ),
529+ ),
530+ ),
531+ )
532+ )
533+ );
534+ expect (find.text ('Index 1' ), findsOneWidget);
535+ expect (tester.getCenter (find.text ('Index 1' )).dy, 51.0 );
536+
537+ final TestGesture pointer1 = await tester.startGesture (tester.getCenter (find.text ('Index 1' )));
538+ // Overscroll the start.
539+ await pointer1.moveBy (const Offset (0.0 , 210.0 ));
540+ await tester.pumpAndSettle ();
541+ expect (find.text ('Index 1' ), findsOneWidget);
542+ double lastStretchedLocation = tester.getCenter (find.text ('Index 1' )).dy;
543+ expect (lastStretchedLocation, greaterThan (51.0 ));
544+
545+ final TestGesture pointer2 = await tester.startGesture (tester.getCenter (find.text ('Index 1' )));
546+ // Add overscroll from an additional pointer
547+ await pointer2.moveBy (const Offset (0.0 , 210.0 ));
548+ await tester.pumpAndSettle ();
549+ expect (find.text ('Index 1' ), findsOneWidget);
550+ expect (tester.getCenter (find.text ('Index 1' )).dy, greaterThan (lastStretchedLocation));
551+ lastStretchedLocation = tester.getCenter (find.text ('Index 1' )).dy;
552+
553+ final TestGesture pointer3 = await tester.startGesture (tester.getCenter (find.text ('Index 1' )));
554+ // Add overscroll from an additional pointer, exceeding the max stretch (600)
555+ await pointer3.moveBy (const Offset (0.0 , 210.0 ));
556+ await tester.pumpAndSettle ();
557+ expect (find.text ('Index 1' ), findsOneWidget);
558+ expect (tester.getCenter (find.text ('Index 1' )).dy, greaterThan (lastStretchedLocation));
559+ lastStretchedLocation = tester.getCenter (find.text ('Index 1' )).dy;
560+
561+ final TestGesture pointer4 = await tester.startGesture (tester.getCenter (find.text ('Index 1' )));
562+ // Since we have maxed out the overscroll, it should not have stretched
563+ // further, regardless of the number of pointers.
564+ await pointer4.moveBy (const Offset (0.0 , 210.0 ));
565+ await tester.pumpAndSettle ();
566+ expect (find.text ('Index 1' ), findsOneWidget);
567+ expect (tester.getCenter (find.text ('Index 1' )).dy, lastStretchedLocation);
568+
569+ await pointer1.up ();
570+ await pointer2.up ();
571+ await pointer3.up ();
572+ await pointer4.up ();
573+ await tester.pumpAndSettle ();
574+ });
454575}
0 commit comments