flutter - How to set fillOverscroll=false on a SliverFillRemaining with a scrollable child (TabView)? - Stack Overflow

admin2025-05-02  0

Goal: Add a TabView to a CustomScrollView.

Approach: Wrap TabView with a SliverFillRemaining

Problem: The CustomScrollView can be scrolled far beyond the bottom of the TabView.

More general problem: I want a SliverAppBar.large followed by (or containing) an image, a title, a TabBar and a TabView.

I have tried to create a more complex SliverAppBar.large but have not succeeded to do so.

Therefore I did the following. Explanation: The SliverFillRemaining has a property fillOverscroll which can be set to false. However, this only works, if the body is not scrollable (hasScrollBody). A TabView is scrollable, so this doesn't work. How can I modify the code, so that the white space disappears?

return DefaultTabController(
        length: 2,
        child: Scaffold(
            body: CustomScrollView(
          slivers: [
            const SliverAppBar.medium(
              title: Text("Title"),
            ),
            SliverToBoxAdapter(
              child: Container(
                height: 100,
                color: Colors.red,
              ),
            ),
            SliverPersistentHeader(
              pinned: true,
              delegate: _TabBarDelegate(
                const TabBar(
                  tabs: [
                    Tab(text: 'Tab1'),
                    Tab(text: 'Tab2'),
                  ],
                ),
              ),
            ),
            
            SliverFillRemaining(
                hasScrollBody: true, 
          // for this to work, the child should not be scrollable
                fillOverscroll: false,
                child: TabBarView(
                        children: [someListView1, someListView2],
                      ),
                    ),
                  ),
          ],
        )));

Goal: Add a TabView to a CustomScrollView.

Approach: Wrap TabView with a SliverFillRemaining

Problem: The CustomScrollView can be scrolled far beyond the bottom of the TabView.

More general problem: I want a SliverAppBar.large followed by (or containing) an image, a title, a TabBar and a TabView.

I have tried to create a more complex SliverAppBar.large but have not succeeded to do so.

Therefore I did the following. Explanation: The SliverFillRemaining has a property fillOverscroll which can be set to false. However, this only works, if the body is not scrollable (hasScrollBody). A TabView is scrollable, so this doesn't work. How can I modify the code, so that the white space disappears?

return DefaultTabController(
        length: 2,
        child: Scaffold(
            body: CustomScrollView(
          slivers: [
            const SliverAppBar.medium(
              title: Text("Title"),
            ),
            SliverToBoxAdapter(
              child: Container(
                height: 100,
                color: Colors.red,
              ),
            ),
            SliverPersistentHeader(
              pinned: true,
              delegate: _TabBarDelegate(
                const TabBar(
                  tabs: [
                    Tab(text: 'Tab1'),
                    Tab(text: 'Tab2'),
                  ],
                ),
              ),
            ),
            
            SliverFillRemaining(
                hasScrollBody: true, 
          // for this to work, the child should not be scrollable
                fillOverscroll: false,
                child: TabBarView(
                        children: [someListView1, someListView2],
                      ),
                    ),
                  ),
          ],
        )));
Share Improve this question asked Jan 2 at 0:05 82beja182beja1 1
Add a comment  | 

1 Answer 1

Reset to default 0

You can try the following approach, which should help resolve the issue you're facing.

Widget HeaderWidget() {
 return Scaffold(
 appBar: AppBar(
 title: Text('Title'),
 elevation: 0.0,
),
body: DefaultTabController(
  length: 2,
  child: NestedScrollView(
    headerSliverBuilder: (context, innerBoxIsScrolled) {
      return [
        SliverToBoxAdapter(
          child: Container(
            color: Colors.red,
            height: 100,
          ),
        ),
        // SliverAppBar to make the TabBar sticky
        SliverAppBar(
          pinned:
              true, // This ensures the TabBar stays visible when scrolling
          floating: true, // Keeps the TabBar at the top of the screen
          expandedHeight: 0,
          // No extra space for the expanded area
          bottom: TabBar(
            tabs: [
              Tab(text: 'Tab 1'),
              Tab(text: 'Tab 2'),
            ],
          ),
        ),
      ];
    },
   
    body: TabBarView(
      children: [
        ListView.builder(
          itemCount: 10, 
          itemBuilder: (context, index) => ListTile(
            tileColor: Colors.green,
            title: Text(
              'Item $index',
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
        ListView.builder(
          itemCount: 5, 
          itemBuilder: (context, index) => ListTile(
            tileColor: Colors.red,
            title: Text(
              'Item $index',
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ],
    ),
   ),
  ),
 );
}
转载请注明原文地址:http://anycun.com/QandA/1746138881a92113.html