最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Flutter pinned SliverPersistentHeader goes behind a transparent AppBar (extendBodyBehindAppBar: true) - Stack Overflow

programmeradmin0浏览0评论

I'm building a Flutter screen that has a transparent AppBar in the parent Scaffold and a child screen (LobbyScreen) with its own CustomScrollView. I want to pin a SliverPersistentHeader below the transparent AppBar. However, when I set extendBodyBehindAppBar: true, my pinned header scrolls behind the AppBar.

class _HomeScreenState extends State<HomeScreen> {
  final ScrollController _homeScrollController = ScrollController();
  late int _selectedIndex = 0;
  late final List<Widget> _homeWidgets = <Widget>[
    LobbyScreen(scrollController: _homeScrollController),
    // ... another screen here ...
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true, // needed for transparency
      appBar: CoruscantHomeTopBarWidget(
        leading: Image.asset(AppImages.topBarLogo),
        trailingBarWidget: /* some trailing widget */,
      ),
      body: _homeWidgets.elementAt(_selectedIndex),
      floatingActionButton: /* ... */,
      bottomNavigationBar: /* ... */,
    );
  }
}

Inside LobbyScreen, I use a CustomScrollView that contains a pinned sliver (CustomStickyTabBarWidget), which internally uses a SliverPersistentHeader:

 class LobbyScreen extends StatelessWidget {
  const LobbyScreen({
    required this.scrollController,
    super.key,
  });

  final ScrollController scrollController;

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      controller: scrollController,
      slivers: <Widget>[
        SliverToBoxAdapter(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 24),
            child: _MatchCardWidget(
              // ...
            ),
          ),
        ),
        const SliverToBoxAdapter(
          child: CoruscantGap(16),
        ),
        SliverToBoxAdapter(
          child: HorizontalMatchCardsWidget(
            // ...
          ),
        ),
        const SliverToBoxAdapter(
          child: CoruscantGap(16),
        ),
        // More SliverToBoxAdapter ...
        
        CustomStickyTabBarWidget(
          initialIndex: 0,
          tabs: tabs,
          tabSlivers: <Widget>[
            SliverPadding(
              padding: const EdgeInsets.symmetric(horizontal: 24),
              sliver: SliverList.builder(
                itemCount: mockLobbyMatch.length,
                itemBuilder: (BuildContext context, int index) {
                  return /* ... cards ... */;
                },
              ),
            ),
            // More slivers for other tabs
          ],
        ),
        
        const SliverToBoxAdapter(
          child: CoruscantGap(16),
        ),
      ],
    );
  }
}

The CustomStickyTabBarWidget uses:

 @override
  Widget build(BuildContext context) {
    return SliverMainAxisGroup(
      slivers: <Widget>[
        SliverPersistentHeader(
          pinned: true,
          delegate: _TabsViewWithFilters(
            currentIndex: _currentIndex,
            // ...
          ),
        ),
        // Show different slivers per tab
        widget.tabSlivers[_tabController.index],
      ],
    );
  }

The Problem: Because extendBodyBehindAppBar: true is set on the Scaffold, the pinned header in LobbyScreen is pinned at the top of its scroll context — which visually places it under the transparent app bar. I’ve tried: Adding a SliverToBoxAdapter(child: SizedBox(height: kToolbarHeight)) at the top of the CustomScrollView in LobbyScreen. It offset the pinned header, but it also disrupted the rest of my layout (extra gap where I don’t want it). Changing the AppBar to a SliverAppBar inside one CustomScrollView, but that conflicts with my existing design and usage of the parent Scaffold.

Question how can I make the tabbarWidget stick under the app bar while keeping my UI same i.e not losing transparency

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论