How to make the TabBar not moving in SliverAppBar?

275 views Asked by At

this is my first question. i'm currently working on sliverAppBar with tabbar. is there anything i can do to make the tabbar to stay on top and not moving down when i drag the sliver down? this is how its looks based on my code and this is my code:

@override
Widget build(BuildContext context) {
  return MaterialApp(
    theme: ThemeData(primaryColor: Colors.green[700]),
    home: DefaultTabController(
      length: 3,
      child: Scaffold(
        body: CustomScrollView(
          slivers: <Widget>[
            SliverAppBar(
              expandedHeight: 450,
              pinned: true,
              bottom: TabBar( 
                tabs: [
                  Tab(icon: Icon(Icons.directions_car)),
                  Tab(icon: Icon(Icons.directions_transit)),
                  Tab(icon: Icon(Icons.directions_bike)),
                ],
              ),
              backgroundColor: Colors.green[700],
              flexibleSpace: FlexibleSpaceBar(
                background: Image.asset(
                  'images/green.png',
                fit: BoxFit.cover,
                ),
              ),
            ),
            SliverFillRemaining(
                child: Container(
              child: Column(
                children: List<int>.generate(12, (index) => index)
                    .map((index) => Container(
                          height: 40,
                          margin: EdgeInsets.symmetric(vertical: 10),
                          color: Colors.grey[300],
                          alignment: Alignment.center,
                          child: Text('$index item'),
                        ))
                    .toList(),
              ),
              decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(15),
                    topRight: Radius.circular(15),
                  )),
            ))
          ],
        ),
      ),
    ),
  );
}
}

edit: i still want the function of the sliver to be able drag down but i want to keep the tab on top and not moving

1

There are 1 answers

2
Mad World On

You have to wrap your CustomScrollView with a stack and position the TabBar above it

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primaryColor: Colors.green[700]),
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          body: Stack(
            children: <Widget>[
              CustomScrollView(
                slivers: <Widget>[
                  SliverAppBar(
                    expandedHeight: 450,
                    pinned: true,
                    backgroundColor: Colors.green[700],
                  ),
                  SliverFillRemaining(
                      hasScrollBody: false,
                      child: Container(
                        child: Column(
                          children: List<int>.generate(12, (index) => index)
                              .map((index) => Container(
                                    height: 40,
                                    margin: EdgeInsets.symmetric(vertical: 10),
                                    color: Colors.grey[300],
                                    alignment: Alignment.center,
                                    child: Text('$index item'),
                                  ))
                              .toList(),
                        ),
                        decoration: BoxDecoration(
                            color: Colors.white,
                            borderRadius: BorderRadius.only(
                              topLeft: Radius.circular(15),
                              topRight: Radius.circular(15),
                            )),
                      ))
                ],
              ),

              /// YOUR TAB WITH ICONS
              Positioned(
                top: MediaQuery.of(context).padding.top,
                child: Container(
                  width: MediaQuery.of(context).size.width,
                  height: 60.0,
                  color: Colors.green[700],
                  child: TabBar(
                    tabs: [
                      Tab(icon: Icon(Icons.directions_car)),
                      Tab(icon: Icon(Icons.directions_transit)),
                      Tab(icon: Icon(Icons.directions_bike)),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

This will not fix the overflow on the bottom tho. If you want to fix that too, just add this hasScrollBody: false, to your SliverFillRemaining like so:

SliverFillRemaining(
     hasScrollBody: false,
     child: Container(...),
),