@@ -976,6 +976,147 @@ void main() {
976976 expect (tester.takeException (), isAssertionError);
977977 });
978978
979+ testWidgets ('Can listen for changes in sheet size' , (WidgetTester tester) async {
980+ const Key stackKey = ValueKey <String >('stack' );
981+ const Key containerKey = ValueKey <String >('container' );
982+ final List <double > loggedSizes = < double > [];
983+ final DraggableScrollableController controller = DraggableScrollableController ();
984+ controller.addListener (() {
985+ loggedSizes.add (controller.size);
986+ });
987+ await tester.pumpWidget (_boilerplate (
988+ null ,
989+ controller: controller,
990+ stackKey: stackKey,
991+ containerKey: containerKey,
992+ ));
993+ await tester.pumpAndSettle ();
994+ final double screenHeight = tester
995+ .getSize (find.byKey (stackKey))
996+ .height;
997+
998+ // The initial size shouldn't be logged because no change has occurred yet.
999+ expect (loggedSizes.isEmpty, true );
1000+
1001+ await tester.drag (find.text ('Item 1' ), Offset (0 , .1 * screenHeight), touchSlopY: 0 );
1002+ await tester.pumpAndSettle ();
1003+ expect (loggedSizes, < double > [.4 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1004+ loggedSizes.clear ();
1005+
1006+ await tester.timedDrag (find.text ('Item 1' ), Offset (0 , - .1 * screenHeight), const Duration (seconds: 1 ), frequency: 2 );
1007+ await tester.pumpAndSettle ();
1008+ expect (loggedSizes, < double > [.45 , .5 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1009+ loggedSizes.clear ();
1010+
1011+ controller.jumpTo (.6 );
1012+ await tester.pumpAndSettle ();
1013+ expect (loggedSizes, < double > [.6 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1014+ loggedSizes.clear ();
1015+
1016+ controller.animateTo (1 , duration: const Duration (milliseconds: 400 ), curve: Curves .linear);
1017+ await tester.pumpAndSettle ();
1018+ expect (loggedSizes, < double > [.7 , .8 , .9 , 1 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1019+ loggedSizes.clear ();
1020+
1021+ DraggableScrollableActuator .reset (tester.element (find.byKey (containerKey)));
1022+ await tester.pumpAndSettle ();
1023+ expect (loggedSizes, < double > [.5 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1024+ loggedSizes.clear ();
1025+ });
1026+
1027+ testWidgets ('Listener does not fire on parameter change and persists after change' , (WidgetTester tester) async {
1028+ const Key stackKey = ValueKey <String >('stack' );
1029+ const Key containerKey = ValueKey <String >('container' );
1030+ final List <double > loggedSizes = < double > [];
1031+ final DraggableScrollableController controller = DraggableScrollableController ();
1032+ controller.addListener (() {
1033+ loggedSizes.add (controller.size);
1034+ });
1035+ await tester.pumpWidget (_boilerplate (
1036+ null ,
1037+ controller: controller,
1038+ stackKey: stackKey,
1039+ containerKey: containerKey,
1040+ ));
1041+ await tester.pumpAndSettle ();
1042+ final double screenHeight = tester
1043+ .getSize (find.byKey (stackKey))
1044+ .height;
1045+
1046+ expect (loggedSizes.isEmpty, true );
1047+
1048+ await tester.drag (find.text ('Item 1' ), Offset (0 , .1 * screenHeight), touchSlopY: 0 );
1049+ await tester.pumpAndSettle ();
1050+ expect (loggedSizes, < double > [.4 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1051+ loggedSizes.clear ();
1052+
1053+ // Update a parameter without forcing a change in the current size.
1054+ await tester.pumpWidget (_boilerplate (
1055+ null ,
1056+ minChildSize: .1 ,
1057+ controller: controller,
1058+ stackKey: stackKey,
1059+ containerKey: containerKey,
1060+ ));
1061+ expect (loggedSizes.isEmpty, true );
1062+
1063+ await tester.drag (find.text ('Item 1' ), Offset (0 , .1 * screenHeight), touchSlopY: 0 );
1064+ await tester.pumpAndSettle ();
1065+ expect (loggedSizes, < double > [.3 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1066+ loggedSizes.clear ();
1067+ });
1068+
1069+ testWidgets ('Listener fires if a parameter change forces a change in size' , (WidgetTester tester) async {
1070+ const Key stackKey = ValueKey <String >('stack' );
1071+ const Key containerKey = ValueKey <String >('container' );
1072+ final List <double > loggedSizes = < double > [];
1073+ final DraggableScrollableController controller = DraggableScrollableController ();
1074+ controller.addListener (() {
1075+ loggedSizes.add (controller.size);
1076+ });
1077+ await tester.pumpWidget (_boilerplate (
1078+ null ,
1079+ controller: controller,
1080+ stackKey: stackKey,
1081+ containerKey: containerKey,
1082+ ));
1083+ await tester.pumpAndSettle ();
1084+ final double screenHeight = tester
1085+ .getSize (find.byKey (stackKey))
1086+ .height;
1087+
1088+ expect (loggedSizes.isEmpty, true );
1089+
1090+ // Set a new `initialChildSize` which will trigger a size change because we
1091+ // haven't moved away initial size yet.
1092+ await tester.pumpWidget (_boilerplate (
1093+ null ,
1094+ initialChildSize: .6 ,
1095+ controller: controller,
1096+ stackKey: stackKey,
1097+ containerKey: containerKey,
1098+ ));
1099+ expect (loggedSizes, < double > [.6 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1100+ loggedSizes.clear ();
1101+
1102+ // Move away from initial child size.
1103+ await tester.drag (find.text ('Item 1' ), Offset (0 , .3 * screenHeight), touchSlopY: 0 );
1104+ await tester.pumpAndSettle ();
1105+ expect (loggedSizes, < double > [.3 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1106+ loggedSizes.clear ();
1107+
1108+ // Set a `minChildSize` greater than the current size.
1109+ await tester.pumpWidget (_boilerplate (
1110+ null ,
1111+ minChildSize: .4 ,
1112+ controller: controller,
1113+ stackKey: stackKey,
1114+ containerKey: containerKey,
1115+ ));
1116+ expect (loggedSizes, < double > [.4 ].map ((double v) => closeTo (v, precisionErrorTolerance)));
1117+ loggedSizes.clear ();
1118+ });
1119+
9791120 testWidgets ('Invalid controller interactions throw assertion errors' , (WidgetTester tester) async {
9801121 final DraggableScrollableController controller = DraggableScrollableController ();
9811122 // Can't use a controller before attaching it.
0 commit comments