如何创建有界可滚动的 TabBarView [英] How to create a bounded scrollable TabBarView

查看:17
本文介绍了如何创建有界可滚动的 TabBarView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 Flutter 中实现如下布局.

当用户滚动时,我希望整个布局滚动(隐藏标题和标签栏).但是,我不能将 TabBarView 嵌套在 ListView 中,因为 TabBarView 没有限定高度,并且 ListView 不为其子级提供限定高度.

我已经看到了这些问题,但对于这个用例,所有问题的答案都不令人满意:

  • 类 SliverWithTabBar 扩展 StatefulWidget {@覆盖_SliverWithTabBarState createState() =>_SliverWithTabBarState();}class _SliverWithTabBarState 扩展状态与 SingleTickerProviderStateMixin {TabController 控制器;@覆盖无效初始化状态(){super.initState();控制器 = TabController(长度: 3, vsync: this);}@覆盖小部件构建(BuildContext 上下文){返回脚手架(正文:嵌套滚动视图(headerSliv​​erBuilder: (BuildContext context, bool innerBoxIsScrolled) {返回 [SliverAppBar(固定:假,背景颜色:颜色.白色,弹性空间:弹性空间条(collapseMode:CollapseMode.pin,背景:列(crossAxisAlignment:CrossAxisAlignment.start,孩子们:<小部件>[容器(高度:200.0,宽度:双无限,颜色:颜色.灰色,孩子:FlutterLogo(),),填充(填充:常量 EdgeInsets.all(10.0),孩子:文本('商务办公',风格:TextStyle(字体大小:25.0),textAlign: TextAlign.left,),),填充(填充:常量 EdgeInsets.all(10.0),孩子:文本('Open now
    Street Address, 299
    City, State',风格:TextStyle(字体大小:15.0),textAlign: TextAlign.left,),),填充(填充:const EdgeInsets.only(右:10.0),孩子:行(mainAxisAlignment: MainAxisAlignment.end,孩子们:<小部件>[图标(图标.share),填充(填充:const EdgeInsets.only(左:10.0),孩子:图标(Icons.favorite),),],),)],),),扩展高度:380.0,底部:标签栏(指示器颜色:颜色.黑色,标签颜色:颜色.黑色,标签:[选项卡(文本:'POSTS'),选项卡(文本:'详细信息'),选项卡(文本:关注者"),],控制器:控制器,),)];},正文:ListView.builder(项目数:100,itemBuilder: (BuildContext context, int index) {退货卡(颜色:索引 % 2 == 0 ?颜色.蓝色:颜色.绿色,孩子:容器(对齐:对齐中心,宽度:双无限,高度:100.0,孩子:文本('颤振很棒',风格:TextStyle(字体大小:18.0),),),);},),),);}}

    你应该寻找 Sliver 小部件来实现 NestedScrollView.

    这为您提供了一个 headerSliv​​erBuilder 属性,您可以在其中实际放置一些标题,当 body 小部件滚动时,您可能会隐藏或固定在屏幕顶部,在这个特定的示例中,一个 列表视图.

    您可能需要查看 RenderSliv​​er 文档.

    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 can't nest a TabBarView inside a ListView since the TabBarView doesn't have a bounded height and ListViews don't provide a bounded height to their children.

    I've already seen these questions, but all of them have unsatisfactory answers for this use case:

    解决方案

    class SliverWithTabBar extends StatefulWidget {
      @override
      _SliverWithTabBarState createState() => _SliverWithTabBarState();
    }
    
    class _SliverWithTabBarState extends State<SliverWithTabBar> 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: <Widget>[
                        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
    Street Address, 299
    City, State',
                            style: TextStyle(fontSize: 15.0),
                            textAlign: TextAlign.left,
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.only(right: 10.0),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: <Widget>[
                              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.

    这篇关于如何创建有界可滚动的 TabBarView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆