flutter 多種情況tabbar高度問題,普通使用和嵌套使用高度問題(Tab)。
眾所周知tabbar的高度是不可改變的。比如我們普通的寫一個tabbar。
先上效果圖:

代碼:
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("這是點贊的內容") ) ], ), ),
可以看到如果沒有任何需求,那么這樣寫完全可以。
Tabbar高度
如果我們的需求只是在上面的基礎上,讓高度小一點,那么可以使用以下方法。
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
普通使用,這樣的方法完全可以。
tabbar頂部懸停(高度自定義)
這個場景是很多開發人員都會用到的。
懸停場景的代碼如下:
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的高度滑動的。所以這個方法在這里就不好用了?。?/p>
經過我的努力攻克SliverAppBar以及bottom的高度修改。。。失敗告終!!!哭。
but,,但是。。功夫不負有心人。找到了另一種方法。也是比較簡單的,可以說非常合適,思路也是簡單明了。
解決辦法:
將SliverAppBar替換掉。NestedScrollView中還有一個組件是SliverPersistentHeader。
SliverPersistentHeader控件當滾動到邊緣時根據滾動的距離縮小高度,有點類似 SliverAppBar 的背景效果。
大家可以看這個,這里就不多說了。
直接先上代碼然后研究:
SafeArea( top: true, child: NestedScrollView( headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return <Widget>[
//寫類似于SliverAppBar中的title部分??梢宰远x圖標,標題,內容 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。
EachTab
https://github.com/LiuC520/flutter_custom_bottom_tab_bar
tab實現了自定義高度,內邊距,以及角標等功能。很不錯的組件。

浙公網安備 33010602011771號