@@ -103,6 +103,56 @@ void main() {
103
103
}
104
104
}
105
105
}
106
+
107
+ testWidgets ('sticky headers: propagate scrollOffsetCorrection properly' , (tester) async {
108
+ Widget page (Widget Function (BuildContext , int ) itemBuilder) {
109
+ return Directionality (textDirection: TextDirection .ltr,
110
+ child: StickyHeaderListView .builder (
111
+ cacheExtent: 0 ,
112
+ itemCount: 10 , itemBuilder: itemBuilder));
113
+ }
114
+
115
+ await tester.pumpWidget (page ((context, i) =>
116
+ StickyHeaderItem (
117
+ allowOverflow: true ,
118
+ header: _Header (i, height: 40 ),
119
+ child: _Item (i, height: 200 ))));
120
+ check (tester.getTopLeft (find.text ("Item 2" ))).equals (Offset (0 , 400 ));
121
+
122
+ // Scroll down (dragging up) to get item 0 off screen.
123
+ await tester.drag (find.text ("Item 2" ), Offset (0 , - 300 ));
124
+ await tester.pump ();
125
+ check (tester.getTopLeft (find.text ("Item 2" ))).equals (Offset (0 , 100 ));
126
+
127
+ // Make the off-screen item 0 taller, so scrolling back up will underflow.
128
+ await tester.pumpWidget (page ((context, i) =>
129
+ StickyHeaderItem (
130
+ allowOverflow: true ,
131
+ header: _Header (i, height: 40 ),
132
+ child: _Item (i, height: i == 0 ? 400 : 200 ))));
133
+ // Confirm the change in item 0's height hasn't already been applied,
134
+ // as it would if the item were within the viewport or its cache area.
135
+ check (tester.getTopLeft (find.text ("Item 2" ))).equals (Offset (0 , 100 ));
136
+
137
+ // Scroll back up (dragging down). This will cause a correction as the list
138
+ // discovers that moving 300px up doesn't reach the start anymore.
139
+ await tester.drag (find.text ("Item 2" ), Offset (0 , 300 ));
140
+
141
+ // As a bonus, mark one of the already-visible items as needing layout.
142
+ // (In a real app, this would typically happen because some state changed.)
143
+ tester.firstElement (find.widgetWithText (SizedBox , "Item 2" ))
144
+ .renderObject! .markNeedsLayout ();
145
+
146
+ // If scrollOffsetCorrection doesn't get propagated to the viewport, this
147
+ // pump will record an exception (causing the test to fail at the end)
148
+ // because the marked item won't get laid out.
149
+ await tester.pump ();
150
+ check (tester.getTopLeft (find.text ("Item 2" ))).equals (Offset (0 , 400 ));
151
+
152
+ // Moreover if scrollOffsetCorrection doesn't get propagated, this item
153
+ // will get placed at zero rather than properly extend up off screen.
154
+ check (tester.getTopLeft (find.text ("Item 0" ))).equals (Offset (0 , - 200 ));
155
+ });
106
156
}
107
157
108
158
Future <void > _checkSequence (
0 commit comments