关于flutter:flutter系列之使用SliverList和SliverGird

2次阅读

共计 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

正文完
 0