如今在 App 中,常見的一個效果就是摺疊工具欄,在 Android 上,這種效果能夠經過 CollapsingToolbarLayout + NestedScrollView + AppBarLayout 來實現,在 Flutter 裏面,也有 NestedScrollView 和 SliverAppBar 來實現這樣的效果。git
先看最簡單的狀況,只使用 AppBargithub
通常狀況下,咱們的 App 都是這樣的:編程
return Scaffold(
appBar: AppBar(
title: Text("標題"),
),
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(title:Text( "標題$index"),);
},
itemCount: 50,
),
);
複製代碼
效果是這樣的:bash
SliverAppBar 實際上是屬於 Slivers 裏面的一個控件,而 Slivers 包含的可滾動的控件通常都是在複雜的滑動嵌套的場景下使用,通常都是做爲 CustomScrollView 的子 Widget 來使用。好比 ListView 對應的 Slivers 組件是 SliverFixedExtentList,GirdView 對應的是 SliverGrid。CustomScrollView 的做用就是使這些 Sliver 組件的滑動效果同一的。微信
若是是使用 NestedScrollView + SliverAppbar 是這樣的:app
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
title: Text("標題"),
floating: false,
snap: false,
pinned: true,
)
];
},
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(title:Text( "標題$index"),);
},
itemCount: 50,
),
),
);
複製代碼
效果:工具
效果其實和上面的同樣。flex
接着把 pined 屬性值改成 false 。效果以下:ui
也就是 pinned 這個屬性能夠控制 AppBar 是否固定。其餘屬性以下:this
const SliverAppBar({
Key key,
this.leading, //在標題左側顯示的一個控件,一般爲一個圖標
this.automaticallyImplyLeading = true,//? 控制是否應該嘗試暗示前導小部件爲null
this.title, //標題
this.actions, //右側的操做菜單,最多三個
this.flexibleSpace, //能夠展開的區域,一般是一個FlexibleSpaceBar
this.bottom, //底部內容區域,一般是 TabBar
this.elevation, //陰影
this.forceElevated = false,
this.backgroundColor, //APP bar 的顏色,默認值爲 ThemeData.primaryColor
this.brightness, //Appbar的主題,有白色和黑色兩種主題
this.iconTheme, //Appbar 上圖標的顏色、透明度、和尺寸信息
this.textTheme, //Appbar 上的文字主題
this.primary = true, //此應用欄是否顯示在屏幕頂部
this.centerTitle, //標題是否居中顯示,默認值根據不一樣的操做系統
this.titleSpacing = NavigationToolbar.kMiddleSpacing,//橫軸上標題內容 周圍的間距
this.expandedHeight, //展開高度
this.floating = false, //是否隨着滑動隱藏標題
this.pinned = false, //是否固定在頂部
this.snap = false, //與floating結合使用
})
複製代碼
指定 flexibleSpace 就能夠定義展開區域。
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
/* SliverAppBar(
title: Text("標題"),
floating: false,
snap: false,
pinned: true,
)
*/
SliverAppBar(
expandedHeight: 200.0,
floating: true,
snap: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text("標題",
style: TextStyle(
color: Colors.redAccent,
fontSize: 16.0,
)),
background: Image.asset(
"images/bg.jpg",
fit: BoxFit.fill,
)
),
)
];
},
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(title:Text( "標題$index"),);
},
itemCount: 50,
),
),
);
複製代碼
效果:
SliverBar 中指定 bottom 屬性爲 TabBar,同時 NestedScrollView body 屬性指定爲 TabVarView
return Scaffold(
body: NestedScrollView(
controller: _scrollviewController,
headerSliverBuilder: (context, boxIsScrolled) {
return [
SliverAppBar(
pinned: true,
floating: true,
elevation: 0.5,
forceElevated: true,
//backgroundColor: Colors.grey,
expandedHeight: 240,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin, //視差效果
background: Container(
//color: Colors.grey,
child: Column(
children: <Widget>[
Container(
height: 210.0,
width: 420,
color: Colors.blue,
child: Image.asset(
"images/bg.jpg",
fit: BoxFit.fitWidth,
),
)
],
),
),
),
bottom: TabBar(controller: _tabController, tabs: [
Tab(
text: "首頁",
),
Tab(
text: "消息",
),
Tab(
text: "購物",
),
Tab(
text: "個人",
)
]),
),
];
},
body: TabBarView(
controller: _tabController,
children: [
Center(
child: Text("one"),
),
Center(
child: Text("two"),
),
Center(
child: Text("three"),
),
Center(
child: Text("four"),
),
]
)
),
);
複製代碼
效果:
歡迎關注「Flutter 編程開發」微信公衆號 。