admin管理员组

文章数量:1123046

I have a layout with three Slivers:

  1. A SliverAppBar (not pinned).
  2. A second SliverAppBar (pinned, containing a SearchBar).
  3. A SliverList.

The issue is with the second SliverAppBar. I want it to be pinned below the status bar, respecting the safe area, but currently, it goes under the status bar, as shown in the second image:

The first drawing represents the default state on launch. When scrolling, the first SliverAppBar disappears as expected, and the second SliverAppBar (with the SearchBar) gets pinned at the top. However, I want the second SliverAppBar to stop just below the status bar instead of going behind it.

What I've Tried:

  1. Wrapping the entire CustomScrollView in a SafeArea:

    • This also shifts my first SliverAppBar, which I don't want.
  2. Wrapping only the second SliverAppBar in a SafeArea or SliverSafeArea:

    • This adds padding between the two SliverAppBars, which is not the desired behavior.
  3. Dynamic padding using a SliverPersistentHeader and working with its shrinkOffset:

    • However, shrinkOffset starts growing only when the header reaches the top of the screen, so it doesn't solve the problem.

Sample code

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  late ScrollController _scrollController;

  @override
  void initState() {
    _scrollController = ScrollController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PrimaryScrollController(
        controller: _scrollController,
        child: CustomScrollView(
          slivers: <Widget>[
            SliverAppBar(
              pinned: false,
              expandedHeight: 200,
              flexibleSpace: FlexibleSpaceBar(
                background: Imagework(
                  '/250?image=9',
                  fit: BoxFit.cover,
                ),
              ),
            ),
            const SliverAppBar(
              pinned: true,
              flexibleSpace: Padding(
                padding: EdgeInsets.only(top: 12.0),
                child: SearchBar(),
              ),
            ),
            SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) {
                  return ListTile(
                    title: Text('Item $index'),
                  );
                },
                childCount: 20,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

How can I achieve this behavior? Is there a proper way to pin a SliverAppBar while respecting the safe area for just that Sliver?

本文标签: flutterHow to Pin a SliverAppBar Below the Status BarStack Overflow