Search code examples
fluttersliverappbar

How to remove empty space in SliverAppBar?


I'm using NestedScrollView here and trying to put a TabBar in the bottom parameter of SliverAppBar which is built in the headerSliverBuilder function. The TabBar works fine but it looks like the SliverAppBar has spared the title some space that makes the tab bar looks weird with large padding above it. Any idea how to remove this space? Thanks in advance.

GIF

 @override
  Widget build(BuildContext context) {
    double screenWidth = MediaQuery.of(context).size.width;
    double screenHeight = MediaQuery.of(context).size.height;
    return Scaffold(
      body: SafeArea(
          child: NestedScrollView(
            headerSliverBuilder: (context, value){
              return[
                SliverOverlapAbsorber(
                  handle:NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                  sliver: SliverAppBar(
                    pinned: true,
                    floating: false,
                    expandedHeight: 500,
                    title: Text("Space that I don't want"),
                    centerTitle: true,
                    flexibleSpace: FlexibleSpaceBar(
                      collapseMode: CollapseMode.pin,
                      background: Container(
                        decoration: BoxDecoration(
                          color: Colors.white,
                          image: DecorationImage(
                            image: AssetImage("assets/images/classroom.png")
                          )
                        ),
                        child: Center(child: Text("Today's lesson cancelled", style: GoogleFonts.montserrat(textStyle: TextStyle(color: Colors.white, fontSize:20, fontWeight: FontWeight.w500),)))
                      ),
                    ),
                    bottom: TabBar(
                      controller: _controller,
                      labelColor: Colors.black,
                      indicatorColor: Colors.black,
                      unselectedLabelColor: Colors.grey,
                      tabs: _tabs.map((String name) => Tab(text: name)).toList()
                    )
                  )
                ),
              ];
            },
            body: TabBarView(
                    controller: _controller,
                    children: (_tabs.map((String name){
                      return SafeArea(
                        child:Builder(
                          builder: (BuildContext context){
                            return CustomScrollView(
                              key: PageStorageKey<String>(name),
                              slivers: <Widget>[
                                SliverOverlapInjector(
                                    handle:NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                                ),
                                SliverToBoxAdapter(
                                  child: _buildLeaderBoardTab(screenWidth,screenHeight)
                                )
                              ],
                            );
                          },
                        )
                      );
                    })).toList(),
                  )
        )
      )
    );
  }

Solution

  • You can wrap the tab bar with a PreferredSize widget of height 0:

    SliverOverlapAbsorber(
                          handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
                              context),
                          sliver: SliverAppBar(
                            bottom: PreferredSize(
                              preferredSize: const Size.fromHeight(0),
                              child: TabBar(
                                  controller: _controller,
                                  labelColor: Colors.black,
                                  indicatorColor: Colors.black,
                                  unselectedLabelColor: Colors.grey,
                                  tabs: _tabs
                                      .map((String name) => Tab(text: name))
                                      .toList()),
                            ),
                            pinned: true,
                            floating: false,
                            expandedHeight: 500,
                            backgroundColor: Colors.white,
                            flexibleSpace: FlexibleSpaceBar(
                              collapseMode: CollapseMode.pin,
                              background: Container(
                                child: child: Center(child: Text("Today's lesson cancelled", style: GoogleFonts.montserrat(textStyle: TextStyle(color: Colors.white, fontSize:20, fontWeight: FontWeight.w500),)))
                                decoration: BoxDecoration(
                                    color: Colors.white,
                                    image: DecorationImage(
                                        fit: BoxFit.cover,
                                        image: DecorationImage(
                                image: AssetImage("assets/images/classroom.png")
                              )
                            ),
                          )),
    

    Note: I used fit: BoxFit.cover for the background image, that's why the tab bar has no white background.

    Result:

    res