标签:body insets bool loading div 关注 double bar tab
先上效果图:
代码:
Scaffold( appBar: AppBar( title: Text("TabBarDemo"), bottom: TabBar( tabs: <Widget>[ Tab(text: "热门"), Tab(text: "推荐"), Tab(text: "关注"), Tab(text: "收藏"), Tab(text: "新增"), Tab(text: "点赞"), ], ), ), body: TabBarView( children: <Widget>[ Center( child: Text("这是热门的内容") ), Center( child: Text("这是推荐的内容") ), Center( child: Text("这是关注的内容") ), Center( child: Text("这是收藏的内容") ), Center( child: Text("这是新增的内容") ), Center( child: Text("这是点赞的内容") ) ], ), ),
可以看到如果没有任何需求,那么这样写完全可以。
如果我们的需求只是在上面的基础上,让高度小一点,那么可以使用以下方法。
PreferredSize( preferredSize: Size(double.infinity, 30),//设置高度为30 child: Container( child: TabBar( controller: this._tabController, indicatorSize: TabBarIndicatorSize.label, tabs: <Widget>[ Tab( child: Text(‘测试‘), ), Tab( child: Text(‘测试‘), ), Tab( child: Text(‘测试‘), ), ], ), ))
因为tabbar的高度是系统内定的,所以不能直接修改,只能在外面嵌套一个PreferredSize来设置固定高度,
preferredSize: Size(double.infinity, 30),//设置高度为30
普通使用,这样的方法完全可以。
这个场景是很多开发人员都会用到的。
悬停场景的代码如下:
SafeArea( top: true, child: NestedScrollView( headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return <Widget>[ SliverAppBar( pinned: true, floating: true, title: Text(‘标题‘), bottom: PreferredSize( preferredSize: Size(double.infinity,30), child:TabBar( labelColor: Colors.black, controller: this._tabController, tabs: <Widget>[ Tab(text: ‘资讯‘), Tab(text: ‘技术‘), Tab(text: ‘技术‘), ], ), ) ), SliverGrid( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 5, mainAxisSpacing: 3), delegate: SliverChildBuilderDelegate((BuildContext context, int index) { return Container( color: Colors.primaries[index % Colors.primaries.length], ); }, childCount: 20), ) ]; }, body: TabBarView( controller: _tabController, //tabbar控制器 children: <Widget>[ // Scaffold( // body: Text(‘sdf‘), // ), Text(‘sdf‘), Text(‘sdf‘), Text(‘sdf‘), ], ), ), );
悬停tabbar主要用到的是SliverAppBar部分,也就是bottom中写的tabbar代码,这样的功能是向上滑动时,title标题隐藏,tabbar悬停在顶部。
可以看到我们用之前的方法PreferredSize设置tabbar的高度为30。接下来看看效果。
可以看到,出现了溢出。为什么呢?使用PreferredSize确实可以修改tabbar的高度。但是在SliverAppBar中bottom的高度是固定的,也就是我们只修改了内部tabbar的高度,实际的滑动高度是以bottom的高度滑动的。所以这个方法在这里就不好用了!!
经过我的努力攻克SliverAppBar以及bottom的高度修改。。。失败告终!!!哭。
but,,但是。。功夫不负有心人。找到了另一种方法。也是比较简单的,可以说非常合适,思路也是简单明了。
将SliverAppBar替换掉。NestedScrollView中还有一个组件是SliverPersistentHeader。
SliverPersistentHeader
控件当滚动到边缘时根据滚动的距离缩小高度,有点类似 SliverAppBar
的背景效果。
大家可以看这个,这里就不多说了。
直接先上代码然后研究:
SafeArea( top: true, child: NestedScrollView( headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return <Widget>[
//写类似于SliverAppBar中的title部分。可以自定义图标,标题,内容 SliverPersistentHeader( delegate: CommonSliverHeaderDelegate( islucency: true, child: PreferredSize( preferredSize: Size.fromHeight(60), child: Row( children: [ Container( padding: EdgeInsets.all(20), alignment: Alignment.center, child: Text(‘sdfsdf‘), ), Container( padding: EdgeInsets.all(20), alignment: Alignment.center, child: Text(‘sdfsdf‘), ), Container( padding: EdgeInsets.all(20), alignment: Alignment.center, child: Icon(Icons.add), ), ], )))),
//tabbar悬停 SliverPersistentHeader( floating: true, pinned: true, delegate: CommonSliverHeaderDelegate( islucency: false, child: PreferredSize( preferredSize: Size(double.infinity, 30), child: Container( child: TabBar( controller: this._tabController, indicatorSize: TabBarIndicatorSize.label, tabs: <Widget>[ Tab( child: Text(‘测试‘), ), Tab( child: Text(‘测试‘), ), Tab( child: Text(‘测试‘), ), ], ), )))), SliverGrid( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 5, mainAxisSpacing: 3), delegate: SliverChildBuilderDelegate((BuildContext context, int index) { return Container( color: Colors.primaries[index % Colors.primaries.length], ); }, childCount: 20), ) ]; }, body: TabBarView( controller: _tabController, //tabbar控制器 children: <Widget>[ // Scaffold( // body: Text(‘sdf‘), // ), Text(‘sdf‘), Text(‘sdf‘), Text(‘sdf‘), ], ), ), );
可以看到代码中的第一个SliverPersistentHeader写的是类似于SliverAppBar中的title组件。
第二个SliverPersistentHeader就是我们实现的tabbar。这个tabbar的高度可以自定义。
SliverPersistentHeader中的floating: true,pinned: true,表示是否可以滑动悬停,因为我们要tabbar悬停在顶部,所以需要写这个,如果不需要悬停的组件,直接不设置就好,效果就是会滑动隐藏掉。
因为我们自定义了CommonSliverHeaderDelegate这个组件,所以设置PreferredSize的高度是有效的。
自定义可以看我另一个文章:flutter SliverPersistentHeader子组件透明度渐变【滑动悬停appbar添加自定义组件的透明度】
这个文章也实现了顶部隐藏淡入淡出的效果。
效果图:
好了到此为止,此功能就算完成了,另外附加一个自定义的tab。
https://github.com/LiuC520/flutter_custom_bottom_tab_bar
tab实现了自定义高度,内边距,以及角标等功能。很不错的组件。
flutter 多种情况tabbar高度问题,普通使用和嵌套使用高度问题(Tab)。
标签:body insets bool loading div 关注 double bar tab
原文地址:https://www.cnblogs.com/zhouyong0330/p/14366263.html