CustomScrollView
一、SliverAppbar 控件介紹
SliverAppBar “應用欄” 相當於升級版的 appbar 於 AppBar 位置的固定的應用最上面的; 而 SliverAppBar 是可以跟隨內容滾動的;
1、使用方法
- 與CustomScrollView、NestedScrollView集成的材質設計應用欄。應用欄由工具欄和其他小部件組成,例如 TabBar和FlexibleSpaceBar。應用欄通常會使用IconButton公開一個或多個常見操作,後者可選地後跟 PopupMenuButton以進行不太常見的操作
- 注意點:
通常結合 CustomScrollView 、 NestedScrollView 來使用它, NestedScrollView裏面可以嵌套Listview 完成滑動
2、基本屬性
const SliverAppBar({
Key key,
this.leading, //在標題左側顯示的一個控件,在首頁通常顯示應用的 logo;在其他界面通常顯示爲返回按鈕
this.automaticallyImplyLeading = true,//? 控制是否應該嘗試暗示前導小部件爲null
this.title, //當前界面的標題文字
this.actions, //一個 Widget 列表,代表 Toolbar 中所顯示的菜單,對於常用的菜單,通常使用 IconButton 來表示;對於不常用的菜單通常使用 PopupMenuButton 來顯示爲三個點,點擊後彈出二級菜單
this.flexibleSpace, //一個顯示在 AppBar 下方的控件,高度和 AppBar 高度一樣, // 可以實現一些特殊的效果,該屬性通常在 SliverAppBar 中使用
this.bottom, //一個 AppBarBottomWidget 對象,通常是 TabBar。用來在 Toolbar 標題下面顯示一個 Tab 導航欄
this.elevation, //陰影
this.forceElevated = false,
this.backgroundColor, //APP bar 的顏色,默認值爲 ThemeData.primaryColor。改值通常和下面的三個屬性一起使用
this.brightness, //App bar 的亮度,有白色和黑色兩種主題,默認值爲 ThemeData.primaryColorBrightness
this.iconTheme, //App bar 上圖標的顏色、透明度、和尺寸信息。默認值爲 ThemeData().primaryIconTheme
this.textTheme, //App bar 上的文字主題。默認值爲 ThemeData().primaryTextTheme
this.primary = true, //此應用欄是否顯示在屏幕頂部
this.centerTitle, //標題是否居中顯示,默認值根據不同的操作系統,顯示方式不一樣,true居中 false居左
this.titleSpacing = NavigationToolbar.kMiddleSpacing,//橫軸上標題內容 周圍的間距
this.expandedHeight, //展開高度
this.floating = false, //是否隨着滑動隱藏標題
this.pinned = false, //是否固定在頂部
this.snap = false, //與floating結合使用
})
3、常用屬性
- 在標題前面顯示的一個控件,在首頁通常顯示應用的logo;在其他界面通常顯示爲返回按鈕。
leading: Icon(_selectedChoice.icon) ,
- 控制是否應該嘗試暗示前導小部件爲null(如果有 leading 這個不會管用 ,相當於忽略這個參數 ; 如果沒有leading ,當有側邊欄的時候, false:不會顯示默認的圖片,true 會顯示 默認圖片,並響應打開側邊欄的事件)
automaticallyImplyLeading:true,
- 當前界面的標題文字
title: Text(_selectedChoice.title )
- 一個 Widget 列表,代表 Toolbar 中所顯示的菜單,對於常用的菜單,通常使用 IconButton 來表示;對於不常用的菜單通常使用 PopupMenuButton 來顯示爲三個點,點擊後彈出二級菜單
actions: <Widget>[
new IconButton( // action button
icon: new Icon(choices[0].icon),
onPressed: () { _select(choices[0]); },
),
new IconButton( // action button
icon: new Icon(choices[1].icon),
onPressed: () { _select(choices[1]); },
),
new PopupMenuButton<Choice>( // overflow menu
onSelected: _select,
itemBuilder: (BuildContext context) {
return choices.skip(2).map((Choice choice) {
return new PopupMenuItem<Choice>(
value: choice,
child: new Text(choice.title),
);
}).toList();
},
)
],
- 一個顯示在 AppBar 下方的控件,高度和 AppBar 高度一樣,可以實現一些特殊的效果,該屬性通常在 SliverAppBar 中使用
flexibleSpace: Container(
color: Colors.blue,
width: MediaQuery.of(context).size.width,
child: Text("aaaaaaaaaa"),
height: 10,
)
- 一個 AppBarBottomWidget 對象,通常是 TabBar。用來在 Toolbar 標題下面顯示一個 Tab 導航欄
bottom: new TabBar(
isScrollable: true,
tabs: choices.map((Choice choice) {
return new Tab(
text: choice.title,
icon: new Icon(choice.icon),
);
}).toList(),
)
- 標題居中顯示
centerTitle: true,
- 此應用欄是否顯示在屏幕頂部
primary: true,
- appbar是否隨着滑動隱藏標題
floating: true,
- tab 是否固定在頂部(爲true是固定,爲false是不固定)
pinned: true,
- 與floating結合使用,如果snap和floating爲true,則浮動應用欄將“捕捉”到視圖中
snap: true,
- 可滾動視圖的高度(默認高度是狀態欄和導航欄的高度,如果有滾動視差的話,要大於前兩者的高度)
expandedHeight: 200.0,
二、CustomScrollView控件介紹
1、使用方法
- CustomScrollView是可以使用sliver來自定義滾動模型(效果)的ScrollView類型的widget。它可以包含多種滾動模型,舉個例子,假設有一個頁面,頂部需要一個GridView,底部需要一個ListView,而要求整個頁面的滑動效果是統一的,即它們看起來是一個整體,如果使用GridView+ListView來實現的話,就不能保證一致的滑動效果,因爲它們的滾動效果是分離的,所以這時就需要一個"膠水",把這些彼此獨立的可滾動widget(Sliver)"粘"起來,而CustomScrollView的功能就相當於“膠水”。
- CustomScrollView讓你可以直接提供 slivers來創建不同的滾動效果,比如Lists,grids 以及 expanding headers。
- Sliver有細片、小片之意,在Flutter中,Sliver通常指具有特定滾動效果的可滾動塊。可滾動widget,如ListView、GridView等都有對應的Sliver實現如SliverList、SliverGrid等。對於大多數Sliver來說,它們和可滾動Widget最主要的區別是Sliver不會包含Scrollable Widget,也就是說Sliver本身不包含滾動交互模型 ,正因如此,CustomScrollView纔可以將多個Sliver"粘"在一起,這些Sliver共用CustomScrollView的Scrollable,最終實現統一的滑動效果。
2、基本屬性
const CustomScrollView({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
Key center,
double anchor = 0.0,
double cacheExtent,
this.slivers = const <Widget>[],
int semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
}) : super(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
center: center,
anchor: anchor,
cacheExtent: cacheExtent,
semanticChildCount: semanticChildCount,
dragStartBehavior: dragStartBehavior,
);
三、CustomScrollView集成SLiverAppBar案例
import 'package:flutter/material.dart';
class CustomScrollViewTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
//因爲本路由沒有使用Scaffold,爲了讓子級Widget(如Text)使用
//Material Design 默認的樣式風格,我們使用Material作爲本路由的根。
return Material(
child: CustomScrollView(
slivers: <Widget>[
//AppBar,包含一個導航欄
SliverAppBar(
pinned: true,
expandedHeight: 250.0,
flexibleSpace: FlexibleSpaceBar(
title: const Text('Demo'),
background: Image.asset(
"./images/avatar.png", fit: BoxFit.cover,),
),
),
SliverPadding(
padding: const EdgeInsets.all(8.0),
sliver: new SliverGrid( //Grid
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, //Grid按兩列顯示
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
//創建子widget
return new Container(
alignment: Alignment.center,
color: Colors.cyan[100 * (index % 9)],
child: new Text('grid item $index'),
);
},
childCount: 20,
),
),
),
//List
new SliverFixedExtentList(
itemExtent: 50.0,
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
//創建列表項
return new Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: new Text('list item $index'),
);
},
childCount: 50 //50個列表項
),
),
],
),
);
}
}
代碼分爲三部分:
- 頭部SliverAppBar:SliverAppBar對應AppBar,兩者不同之處在於SliverAppBar可以集成到CustomScrollView。SliverAppBar可以結合FlexibleSpaceBar實現Material Design中頭部伸縮的模型,具體效果,讀者可以運行該示例查看。
- 中間的SliverGrid:它用SliverPadding包裹以給SliverGrid添加補白。SliverGrid是一個兩列,寬高比爲4的網格,它有20個子組件。
- 底部SliverFixedExtentList:它是一個所有子元素高度都爲50像素的列表。