共计 4173 个字符,预计需要花费 11 分钟才能阅读完成。
简介
在上一篇文章咱们解说 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