简介
在上一篇文章咱们解说SliverAppBar的时候有提到过,Sliver的组件个别都用在CustomScrollView中。除了SliverAppBar之外,咱们还能够为CustomScrollView增加List或者Grid来实现更加简单的组合成果。
明天要向大家介绍的就是SliverList和SliverGird。
SliverList和SliverGird详解
从名字就能够看出SliverList和SliverGird别离是List和Grid的一种,他们和List与Grid最大的区别在于,他们能够管制子widget在main axis和cross axis之间的距离,并且能够通过Extent属性来管制子widget的大小,十分的弱小。
咱们先来看下这两个组件的定义和构造函数:
class SliverList extends SliverMultiBoxAdaptorWidget { /// Creates a sliver that places box children in a linear array. const SliverList({ Key? key, required SliverChildDelegate delegate, }) : super(key: key, delegate: delegate);
SliverList继承自SliverMultiBoxAdaptorWidget,它的构造函数比较简单,须要传入一个SliverChildDelegate的参数,这里的SliverChildDelegate应用的是delegate的办法来创立SliverList的子组件。
SliverChildDelegate是一个抽象类,它有两个实现类,别离是SliverChildBuilderDelegate和SliverChildListDelegate。
其中SliverChildBuilderDelegate是用的builder模式来生成子widget,在上一篇文章中,咱们构建SliverList就是应用的这个builder类。
SliverChildBuilderDelegate应用builder来生成子Widget,而SliverChildListDelegate须要传入一个childList来实现结构,也就是说SliverChildListDelegate须要一个确切的childList,而不是用builder来构建。
要留神的是SliverList并不能指定子widget的extent大小,如果你想指定List中的子widget的extent大小的话,那么能够应用SliverFixedExtentList:
class SliverFixedExtentList extends SliverMultiBoxAdaptorWidget { const SliverFixedExtentList({ Key? key, required SliverChildDelegate delegate, required this.itemExtent, }) : super(key: key, delegate: delegate);
能够看到SliverFixedExtentList和SliverList相比,多了一个itemExtent参数,用来管制子widget在main axis上的大小。
而后咱们再来看一下SliverGird:
class SliverGrid extends SliverMultiBoxAdaptorWidget { /// Creates a sliver that places multiple box children in a two dimensional /// arrangement. const SliverGrid({ Key? key, required SliverChildDelegate delegate, required this.gridDelegate, }) : super(key: key, delegate: delegate);
SliverGrid也是继承自SliverMultiBoxAdaptorWidget,和SliverList一样,它也有一个SliverChildDelegate的参数,另外它还多了一个gridDelegate的参数用来管制gird的布局。
这里的gridDelegate是一个SliverGridDelegate类型的参数,用来管制children的size和position。
SliverGridDelegate也是一个抽象类,它有两个实现类,别离是SliverGridDelegateWithMaxCrossAxisExtent和SliverGridDelegateWithFixedCrossAxisCount,这两个实现类的区别就在于MaxCrossAxisExtent和FixedCrossAxisCount的区别。
怎么了解MaxCrossAxisExtent呢?比如说这个Grid是竖向的,而后Gird的宽度是500.0,如果MaxCrossAxisExtent=100,那么delegate将会创立5个column,每个column的宽度是100。
crossAxisCount则是间接指定cross axis的child个数有多少。
SliverList和SliverGird的应用
有了下面介绍的SliverList和SliverGird的构造函数,接下来咱们具体来看下如何在我的项目中应用SliverList和SliverGird。
默认状况下SliverList和SliverGird是须要和CustomScrollView一起应用的,所以咱们先创立一个CustomScrollView,在它的slivers属性中,放入一个SliverAppBar组件:
CustomScrollView( slivers: <Widget>[ const SliverAppBar( pinned: true, snap: false, floating: false, expandedHeight: 200.0, flexibleSpace: FlexibleSpaceBar( title: Text('SliverList and SliverGrid'), ), ), ], );
SliverAppBar只是一个AppBar,运行能够失去上面的界面:
咱们还须要为它持续增加其余的slivers组件。
首先给他增加一个SliverGrid:
SliverGrid( gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 200.0, mainAxisSpacing: 20.0, crossAxisSpacing: 50.0, childAspectRatio: 4.0, ), delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return Container( alignment: Alignment.center, color: Colors.green[100 * (index % 9)], child: Text('grid item $index'), ); }, childCount: 20, ), ),
这里咱们设置了gridDelegate属性,并且自定义了SliverChildBuilderDelegate,用来生成20个Container。
运行失去的界面如下:
而后为其增加SliverList:
SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return Container( color: index.isOdd ? Colors.white : Colors.green, height: 50.0, child: Center( child: ListTile( title: Text( '100' + index.toString(), style: const TextStyle(fontWeight: FontWeight.w500), ), leading: Icon( Icons.account_box, color: Colors.green[100 * (index % 9)], ), ), ), ); }, childCount: 15, ), ),
因为SliverList只须要传入一个delegate参数,这里咱们生成了15个child组件。生成的界面如下:
因为SliverList不能管制List中子widget的extent,所以咱们再增加一个SliverFixedExtentList看看成果:
SliverFixedExtentList( itemExtent: 100.0, delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return Container( color: index.isOdd ? Colors.white : Colors.green, height: 50.0, child: Center( child: ListTile( title: Text( '200' + index.toString(), style: const TextStyle(fontWeight: FontWeight.w500), ), leading: Icon( Icons.account_box, color: Colors.green[100 * (index % 9)], ), ), ), ); }, childCount: 15, ),
SliverFixedExtentList和SliverList相比多了一个itemExtent属性,这里咱们将其设置为100,运行能够失去上面的界面:
能够看到List中的子Widget高度产生了变动。
总结
在CustomScrollView中应用SliverList和SliverGird,能够实现灵便的出现成果。
本文的例子:https://github.com/ddean2009/learn-flutter.git