在上篇文章中我們學了SingleChildScrollView
這個滑動控件,現在我們學習一下CustomScrollView
這個控件。
CustomScrollView這個控件是針對多個滾動佈局的組件,比如頂部一個GridView
,底部又來一個ListView
,而要求兩個界面具有聯動性,如果是單純的GridView
跟ListView
的話,這時候並不能保證一致的滑動性,比如,GridView
滑動完ListView
再進行滑動。這時候我們就需要一個膠水
,把這些彼此獨立的可滾動組件粘
起來,恰恰CustomScrollView
就是膠水
的角色。所以:CustomScrollView
可以又多個滑動的組件,且它的子組件都是遵循Sliver(薄片)
的功能,共用CustomScrollView
的Scrollable
。一般的,這些組件差不多都是Sliver
開頭,如:
SliverAppBar,
SliverPadding,
SliverFixedExtentList,
SliverList
等等。
如何區分一個子組件是否是Sliver
?
如果直接將ListView、GridView
作爲CustomScrollView
是不行的,因爲它們本身是可滾動組件而並不是Sliver
!因此,爲了能讓可滾動組件能和CustomScrollView
配合使用,Flutter提供了一些可滾動組件的Sliver
版,如SliverList、SliverGrid
等。實際上Sliver
版的可滾動組件和非Sliver版的可滾動組件最大的區別就是前者不包含滾動模型(自身不能再滾動),而後者包含滾動模型
個人通俗一點理解就是:ListView、GridView
這些組件本身已經是可滾動組件了,所以它們就不能再被嵌套在CustomScrollView
中了。
而在CustomScrollView
中的Sliver(薄片)
組件多以Sliver開頭
,如SliverAppBar
,SliverList
等等。
下面引用一段CustomScrollView
中含多個Sliver
薄片的代碼,頁面。
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個列表項
),
),
],
),
);
}
}
試着跑一下?