CustomScrollView 和 Slivers

62 阅读2分钟

1、ListView、GridView、PageView 都是一个完整的可滚动组件,所谓完整是指它们都包括Scrollable 、 Viewport 和 Sliver

2、假如想要在一个页面中,同时包含多个可滚动组件,且使它们的滑动效果能统一起来,

3、比如:想将已有的两个沿垂直方向滚动的 ListView 成一个 ListView ,这样在第一ListView 滑动到底部时能自动接上第二 ListView

4、页面中有两个 ListView,各占可视区域一半高度,虽然能够显式出来,但每一个 ListView 只会响应自己可视区域中滑动,实现不了我们想要的效果。

原因是两个 ListView 都有自己独立的 Scrollable 、 Viewport 和 Sliver

CustomScrollView 组件来帮助我们创建一个公共的 Scrollable 和 Viewport ,然后它的 slivers 参数接受一个 Sliver 数组即可解决问题;

Widget buildTwoSliverList() {
  // SliverFixedExtentList 是一个 Sliver,它可以生成高度相同的列表项。
  // 再次提醒,如果列表项高度相同,我们应该优先使用SliverFixedExtentList 
  // 和 SliverPrototypeExtentList,如果不同,使用 SliverList.
  var listView = SliverFixedExtentList(
    itemExtent: 56, //列表项高度固定
    delegate: SliverChildBuilderDelegate(
      (_, index) => ListTile(title: Text('$index')),
      childCount: 10,
    ),
  );
  // 使用
  return CustomScrollView(
    slivers: [
      listView,
      listView,
    ],
  );
}

CustomScrollView 的主要功能是提供一个公共的 Scrollable 和 Viewport,来组合多个 Sliver,CustomScrollView 的结构如图:

image.png

Flutter 中常用的 Sliver

image.png

除了和列表对应的 Sliver 之外还有一些用于对 Sliver 进行布局、装饰的组件,它们的子组件必须是 Sliver,列举几个常用的:

image.png

SliverToBoxAdapter

通常需要往 CustomScrollView 中添加一些自定义的组件,而这些组件并非都有 Sliver 版本,为此 Flutter 提供了一个 SliverToBoxAdapter 组件,它是一个适配器:可以将 RenderBox 适配为 Slive

注意:如果 CustomScrollView 有孩子也是一个完整的可滚动组件且它们的滑动方向一致,则 CustomScrollView 不能正常工作

SliverPersistentHeader

SliverPersistentHeader 的定义:

const SliverPersistentHeader({
  Key? key,
  // 构造 header 组件的委托
  required SliverPersistentHeaderDelegate delegate,
  this.pinned = false, // header 滑动到可视区域顶部时是否固定在顶部
  this.floating = false, // 正文部分介绍
})