How to create a bounded scrollable TabBarView

后端 未结 2 493
北海茫月
北海茫月 2020-12-16 02:32

I need to implement the following layout in Flutter.

When the user scrolls, I want the entire layout to scroll (hiding the header and tab bar). However, I c

2条回答
  •  萌比男神i
    2020-12-16 03:10

    class SliverWithTabBar extends StatefulWidget {
      @override
      _SliverWithTabBarState createState() => _SliverWithTabBarState();
    }
    
    class _SliverWithTabBarState extends State with SingleTickerProviderStateMixin {
      TabController controller;
    
      @override
      void initState() {
        super.initState();
        controller = TabController(length: 3, vsync: this);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: NestedScrollView(
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return [
                SliverAppBar(
                  pinned: false,
                  backgroundColor: Colors.white,
                  flexibleSpace: FlexibleSpaceBar(
                    collapseMode: CollapseMode.pin,
                    background: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Container(
                          height: 200.0,
                          width: double.infinity,
                          color: Colors.grey,
                          child: FlutterLogo(),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(10.0),
                          child: Text(
                            'Business Office',
                            style: TextStyle(fontSize: 25.0),
                            textAlign: TextAlign.left,
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(10.0),
                          child: Text(
                            'Open now\nStreet Address, 299\nCity, State',
                            style: TextStyle(fontSize: 15.0),
                            textAlign: TextAlign.left,
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.only(right: 10.0),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: [
                              Icon(Icons.share),
                              Padding(
                                padding: const EdgeInsets.only(left: 10.0),
                                child: Icon(Icons.favorite),
                              ),
                            ],
                          ),
                        )
                      ],
                    ),
                  ),
                  expandedHeight: 380.0,
                  bottom: TabBar(
                    indicatorColor: Colors.black,
                    labelColor: Colors.black,
                    tabs: [
                      Tab(text: 'POSTS'),
                      Tab(text: 'DETAILS'),
                      Tab(text: 'FOLLOWERS'),
                    ],
                    controller: controller,
                  ),
                )
              ];
            },
            body: ListView.builder(
              itemCount: 100,
              itemBuilder: (BuildContext context, int index) {
                return Card(
                  color: index % 2 == 0 ? Colors.blue : Colors.green,
                  child: Container(
                    alignment: Alignment.center,
                    width: double.infinity,
                    height: 100.0,
                    child: Text(
                      'Flutter is awesome',
                      style: TextStyle(fontSize: 18.0),
                    ),
                  ),
                );
              },
            ),
          ),
        );
      }
    }
    

    You should look for Sliver widgets to achieve NestedScrollView.

    That gives you a headerSliverBuilder property where you can actually fit some headers that you might hide or pin on the top of the screen when the body widget is scrolled, in this particular example, a ListView.

    You might want to take a look to the RenderSliver documentation.

提交回复
热议问题