@@ -2337,6 +2337,121 @@ void main() {
2337
2337
},
2338
2338
);
2339
2339
2340
+ testWidgets (
2341
+ 'Large title and bottom snap up when partially scrolled over halfway up in always mode' ,
2342
+ (WidgetTester tester) async {
2343
+ final ScrollController scrollController = ScrollController ();
2344
+ addTearDown (scrollController.dispose);
2345
+ const double largeTitleHeight = 52.0 ;
2346
+ const double bottomHeight = 100.0 ;
2347
+
2348
+ await tester.pumpWidget (
2349
+ CupertinoApp (
2350
+ home: CustomScrollView (
2351
+ controller: scrollController,
2352
+ slivers: const < Widget > [
2353
+ CupertinoSliverNavigationBar (
2354
+ largeTitle: Text ('Large title' ),
2355
+ middle: Text ('middle' ),
2356
+ alwaysShowMiddle: false ,
2357
+ bottom: PreferredSize (
2358
+ preferredSize: Size .fromHeight (bottomHeight),
2359
+ child: Placeholder (),
2360
+ ),
2361
+ bottomMode: NavigationBarBottomMode .always,
2362
+ ),
2363
+ SliverFillRemaining (child: SizedBox (height: 1000.0 )),
2364
+ ],
2365
+ ),
2366
+ ),
2367
+ );
2368
+
2369
+ final RenderAnimatedOpacity ? renderOpacity =
2370
+ tester
2371
+ .element (find.text ('middle' ))
2372
+ .findAncestorRenderObjectOfType <RenderAnimatedOpacity >();
2373
+ final Finder bottomFinder = find.byType (Placeholder );
2374
+
2375
+ expect (renderOpacity? .opacity.value, 0.0 );
2376
+ expect (scrollController.position.pixels, 0.0 );
2377
+
2378
+ // Scroll to just past the halfway point of the large title.
2379
+ final TestGesture scrollGesture1 = await tester.startGesture (
2380
+ tester.getCenter (find.byType (Scrollable )),
2381
+ );
2382
+ await scrollGesture1.moveBy (const Offset (0.0 , - (largeTitleHeight / 2 ) - 1 ));
2383
+ await scrollGesture1.up ();
2384
+ await tester.pumpAndSettle ();
2385
+
2386
+ // Expect the large title to snap up to the persistent nav bar.
2387
+ expect (scrollController.position.pixels, largeTitleHeight);
2388
+ expect (renderOpacity? .opacity.value, 1.0 );
2389
+
2390
+ // Scroll to just past the halfway point of the bottom widget.
2391
+ final TestGesture scrollGesture2 = await tester.startGesture (
2392
+ tester.getCenter (find.byType (Scrollable )),
2393
+ );
2394
+ await scrollGesture2.moveBy (const Offset (0.0 , - (bottomHeight / 2 ) - 1 ));
2395
+ await scrollGesture2.up ();
2396
+ await tester.pumpAndSettle ();
2397
+
2398
+ // The bottom widget is still fully extended.
2399
+ expect (scrollController.position.pixels, largeTitleHeight + (bottomHeight / 2 ) + 1 );
2400
+ expect (
2401
+ tester.getBottomLeft (bottomFinder).dy - tester.getTopLeft (bottomFinder).dy,
2402
+ bottomHeight,
2403
+ );
2404
+ expect (renderOpacity? .opacity.value, 1.0 );
2405
+ },
2406
+ );
2407
+
2408
+ testWidgets (
2409
+ 'Large title and bottom snap down when partially scrolled halfway up or less in always mode' ,
2410
+ (WidgetTester tester) async {
2411
+ final ScrollController scrollController = ScrollController ();
2412
+ addTearDown (scrollController.dispose);
2413
+ const double largeTitleHeight = 52.0 ;
2414
+
2415
+ await tester.pumpWidget (
2416
+ CupertinoApp (
2417
+ home: CustomScrollView (
2418
+ controller: scrollController,
2419
+ slivers: const < Widget > [
2420
+ CupertinoSliverNavigationBar (
2421
+ largeTitle: Text ('Large title' ),
2422
+ middle: Text ('middle' ),
2423
+ alwaysShowMiddle: false ,
2424
+ bottom: PreferredSize (preferredSize: Size .fromHeight (100.0 ), child: Placeholder ()),
2425
+ bottomMode: NavigationBarBottomMode .always,
2426
+ ),
2427
+ SliverFillRemaining (child: SizedBox (height: 1000.0 )),
2428
+ ],
2429
+ ),
2430
+ ),
2431
+ );
2432
+
2433
+ final RenderAnimatedOpacity ? renderOpacity =
2434
+ tester
2435
+ .element (find.text ('middle' ))
2436
+ .findAncestorRenderObjectOfType <RenderAnimatedOpacity >();
2437
+
2438
+ expect (renderOpacity? .opacity.value, 0.0 );
2439
+ expect (scrollController.offset, 0.0 );
2440
+
2441
+ // Scroll to the halfway point of the large title.
2442
+ final TestGesture scrollGesture1 = await tester.startGesture (
2443
+ tester.getCenter (find.byType (Scrollable )),
2444
+ );
2445
+ await scrollGesture1.moveBy (const Offset (0.0 , - largeTitleHeight / 2 ));
2446
+ await scrollGesture1.up ();
2447
+ await tester.pumpAndSettle ();
2448
+
2449
+ // Expect the large title and bottom to snap back to their extended height.
2450
+ expect (scrollController.position.pixels, 0.0 );
2451
+ expect (renderOpacity? .opacity.value, 0.0 );
2452
+ },
2453
+ );
2454
+
2340
2455
testWidgets ('CupertinoNavigationBar with bottom widget' , (WidgetTester tester) async {
2341
2456
const double persistentHeight = 44.0 ;
2342
2457
const double bottomHeight = 10.0 ;
0 commit comments