@@ -69,7 +69,7 @@ void main() {
69
69
final ScrollPosition position = tester.state <ScrollableState >(find.byType (Scrollable )).position;
70
70
position.animateTo (RenderBigSliver .height + delegate.maxExtent - 5.0 , curve: Curves .linear, duration: const Duration (minutes: 1 ));
71
71
await tester.pumpAndSettle (const Duration (milliseconds: 1000 ));
72
- final RenderBox box = tester.renderObject <RenderBox >(find.byType ( Container ));
72
+ final RenderBox box = tester.renderObject <RenderBox >(find.text ( 'Sliver App Bar' ));
73
73
final Rect rect = Rect .fromPoints (box.localToGlobal (Offset .zero), box.localToGlobal (box.size.bottomRight (Offset .zero)));
74
74
expect (rect, equals (const Rect .fromLTWH (0.0 , - 195.0 , 800.0 , 200.0 )));
75
75
});
@@ -95,14 +95,14 @@ void main() {
95
95
),
96
96
);
97
97
98
- expect (tester.getTopLeft (find.byType ( Container )), Offset .zero);
98
+ expect (tester.getTopLeft (find.text ( 'Sliver App Bar' )), Offset .zero);
99
99
expect (tester.getTopLeft (find.text ('X' )), const Offset (0.0 , 200.0 ));
100
100
101
101
final ScrollPosition position = tester.state <ScrollableState >(find.byType (Scrollable )).position;
102
102
position.jumpTo (- 50.0 );
103
103
await tester.pump ();
104
104
105
- expect (tester.getTopLeft (find.byType ( Container )), Offset .zero);
105
+ expect (tester.getTopLeft (find.text ( 'Sliver App Bar' )), Offset .zero);
106
106
expect (tester.getTopLeft (find.text ('X' )), const Offset (0.0 , 250.0 ));
107
107
});
108
108
@@ -127,16 +127,148 @@ void main() {
127
127
),
128
128
);
129
129
130
- expect (tester.getTopLeft (find.byType ( Container )), Offset .zero);
130
+ expect (tester.getTopLeft (find.text ( 'Sliver App Bar' )), Offset .zero);
131
131
expect (tester.getTopLeft (find.text ('X' )), const Offset (0.0 , 200.0 ));
132
132
133
133
final ScrollPosition position = tester.state <ScrollableState >(find.byType (Scrollable )).position;
134
134
position.jumpTo (- 50.0 );
135
135
await tester.pump ();
136
136
137
- expect (tester.getTopLeft (find.byType ( Container )), Offset .zero);
137
+ expect (tester.getTopLeft (find.text ( 'Sliver App Bar' )), Offset .zero);
138
138
expect (tester.getTopLeft (find.text ('X' )), const Offset (0.0 , 250.0 ));
139
139
});
140
+
141
+ group ('has correct semantics when' , () {
142
+ testWidgets ('within viewport' , (WidgetTester tester) async {
143
+ const double cacheExtent = 250 ;
144
+ final SemanticsHandle handle = tester.ensureSemantics ();
145
+
146
+ await tester.pumpWidget (
147
+ Directionality (
148
+ textDirection: TextDirection .ltr,
149
+ child: CustomScrollView (
150
+ cacheExtent: cacheExtent,
151
+ physics: const BouncingScrollPhysics (),
152
+ slivers: < Widget > [
153
+ SliverPersistentHeader (delegate: TestDelegate ()),
154
+ const SliverList (
155
+ delegate: SliverChildListDelegate .fixed (< Widget > [
156
+ SizedBox (
157
+ height: 300.0 ,
158
+ child: Text ('X' ),
159
+ ),
160
+ ]),
161
+ ),
162
+ ],
163
+ ),
164
+ ),
165
+ );
166
+
167
+ final SemanticsFinder sliverAppBar = find.semantics.byLabel (
168
+ 'Sliver App Bar' ,
169
+ );
170
+
171
+ expect (sliverAppBar, findsOne);
172
+ expect (sliverAppBar, containsSemantics (isHidden: false ));
173
+ handle.dispose ();
174
+ });
175
+
176
+ testWidgets ('partially scrolling off screen' , (WidgetTester tester) async {
177
+ final GlobalKey key = GlobalKey ();
178
+ final TestDelegate delegate = TestDelegate ();
179
+ final SemanticsHandle handle = tester.ensureSemantics ();
180
+ const double cacheExtent = 250 ;
181
+ await tester.pumpWidget (
182
+ Directionality (
183
+ textDirection: TextDirection .ltr,
184
+ child: CustomScrollView (
185
+ cacheExtent: cacheExtent,
186
+ slivers: < Widget > [
187
+ SliverPersistentHeader (key: key, delegate: delegate),
188
+ const BigSliver (),
189
+ const BigSliver (),
190
+ ],
191
+ ),
192
+ ),
193
+ );
194
+ final ScrollPosition position = tester.state <ScrollableState >(find.byType (Scrollable )).position;
195
+ position.animateTo (delegate.maxExtent - 20.0 , curve: Curves .linear, duration: const Duration (minutes: 1 ));
196
+ await tester.pumpAndSettle (const Duration (milliseconds: 1000 ));
197
+ final RenderBox box = tester.renderObject <RenderBox >(find.text ('Sliver App Bar' ));
198
+ final Rect rect = Rect .fromPoints (box.localToGlobal (Offset .zero), box.localToGlobal (box.size.bottomRight (Offset .zero)));
199
+ expect (rect, equals (const Rect .fromLTWH (0.0 , - 180.0 , 800.0 , 200.0 )));
200
+
201
+ final SemanticsFinder sliverAppBar = find.semantics.byLabel (
202
+ 'Sliver App Bar' ,
203
+ );
204
+
205
+ expect (sliverAppBar, findsOne);
206
+ expect (sliverAppBar, containsSemantics (isHidden: false ));
207
+ handle.dispose ();
208
+ });
209
+
210
+
211
+ testWidgets ('completely scrolling off screen but within cache extent' , (WidgetTester tester) async {
212
+ final GlobalKey key = GlobalKey ();
213
+ final TestDelegate delegate = TestDelegate ();
214
+ final SemanticsHandle handle = tester.ensureSemantics ();
215
+ const double cacheExtent = 250 ;
216
+ await tester.pumpWidget (
217
+ Directionality (
218
+ textDirection: TextDirection .ltr,
219
+ child: CustomScrollView (
220
+ cacheExtent: cacheExtent,
221
+ slivers: < Widget > [
222
+ SliverPersistentHeader (key: key, delegate: delegate),
223
+ const BigSliver (),
224
+ const BigSliver (),
225
+ ],
226
+ ),
227
+ ),
228
+ );
229
+ final ScrollPosition position = tester.state <ScrollableState >(find.byType (Scrollable )).position;
230
+ position.animateTo (delegate.maxExtent + 20.0 , curve: Curves .linear, duration: const Duration (minutes: 1 ));
231
+ await tester.pumpAndSettle (const Duration (milliseconds: 1000 ));
232
+
233
+ final SemanticsFinder sliverAppBar = find.semantics.byLabel (
234
+ 'Sliver App Bar' ,
235
+ );
236
+
237
+ expect (sliverAppBar, findsOne);
238
+ expect (sliverAppBar, containsSemantics (isHidden: true ));
239
+ handle.dispose ();
240
+ });
241
+
242
+ testWidgets ('completely scrolling off screen and not within cache extent' , (WidgetTester tester) async {
243
+ final GlobalKey key = GlobalKey ();
244
+ final TestDelegate delegate = TestDelegate ();
245
+ final SemanticsHandle handle = tester.ensureSemantics ();
246
+ const double cacheExtent = 250 ;
247
+ await tester.pumpWidget (
248
+ Directionality (
249
+ textDirection: TextDirection .ltr,
250
+ child: CustomScrollView (
251
+ cacheExtent: cacheExtent,
252
+ slivers: < Widget > [
253
+ SliverPersistentHeader (key: key, delegate: delegate),
254
+ const BigSliver (),
255
+ const BigSliver (),
256
+ ],
257
+ ),
258
+ ),
259
+ );
260
+ final ScrollPosition position = tester.state <ScrollableState >(find.byType (Scrollable )).position;
261
+ position.animateTo (delegate.maxExtent + 300.0 , curve: Curves .linear, duration: const Duration (minutes: 1 ));
262
+ await tester.pumpAndSettle (const Duration (milliseconds: 1000 ));
263
+
264
+ final SemanticsFinder sliverAppBar = find.semantics.byLabel (
265
+ 'Sliver App Bar' ,
266
+ );
267
+
268
+ expect (sliverAppBar, findsNothing);
269
+ handle.dispose ();
270
+ });
271
+ });
140
272
}
141
273
142
274
class TestDelegate extends SliverPersistentHeaderDelegate {
@@ -148,7 +280,7 @@ class TestDelegate extends SliverPersistentHeaderDelegate {
148
280
149
281
@override
150
282
Widget build (BuildContext context, double shrinkOffset, bool overlapsContent) {
151
- return Container (height: maxExtent);
283
+ return SizedBox (height: maxExtent, child : const Text ( 'Sliver App Bar' ), );
152
284
}
153
285
154
286
@override
0 commit comments