目录
[一些常见的 Sliver 小部件及其用途](#一些常见的 Sliver 小部件及其用途)
[SliverPersistentHeader 与 SliverAppBar 的区别](#SliverPersistentHeader 与 SliverAppBar 的区别)
引
Flutter 的 Sliver 家族是一组专为构建复杂的滚动效果而设计的小部件。在 Flutter 中,Slivers 主要用于自定义滚动视图,允许开发者实现各种复杂的滚动效果和布局。Slivers 特别适合构建那些需要精细滚动控制的高级布局,比如可折叠的应用栏(App Bars)、懒加载列表、网格布局等。
一些常见的 Sliver 小部件及其用途
-
SliverAppBar:这是一个非常流行的 Sliver 小部件,它可以创建一个在页面滚动时动态变化的应用栏。SliverAppBar 可以配置成展开时有一个大的标题和背景图片,而在向上滚动时缩小并固定在页面顶部。
-
SliverList:这个小部件用于显示一个线性的列表项目。它工作在 Sliver 家族中,可以在滚动视图中用来展示一系列的子部件。
-
SliverFixedExtentList:这是一个特定高度项的 SliverList。它要求所有的子项有相同的固定高度,这可以优化性能,因为所有的子项渲染高度是预先知道的。
-
SliverGrid:这个小部件用于创建网格布局。它可以显示多列的子部件,并且每个子部件可以是相同或不同的大小。SliverGrid 对于展示产品目录、图片库等场景非常有用。
-
SliverPadding:这个小部件用于给 Sliver 小部件添加填充。它可以确保 Sliver 小部件在滚动视图中有正确的边距。
-
SliverToBoxAdapter:这个小部件用于将常规的小部件插入到 Sliver 家族中。如果你有一个非 Sliver 的小部件但想要在 Sliver 列表中显示,可以使用 SliverToBoxAdapter 来实现。
Dart
CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: Container(
height: 200.0,
color: Colors.blue,
child: Center(
child: Text('我不是 Sliver 小部件'),
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
title: Text('列表项 $index'),
),
childCount: 100,
),
),
],
)
-
SliverPersistentHeader:这个小部件用于创建在滚动时会保持可见的头部。它可以定制和实现复杂的滚动效果,比如渐变的标题栏。
-
SliverFillRemaining:这个小部件用于填充滚动视图的剩余空间。它常用于创建一个填满屏幕剩余部分的小部件,无论剩余空间有多大。
SliverPersistentHeader 与 SliverAppBar 的区别
看了上面你可能会觉得这两个控件好像干的一个事,但这里额外解释:
- SliverAppBar 是专门用于创建应用栏的,它提供了许多现成的配置选项,如自动隐藏、展开/收缩的效果、背景图片等。
- SliverPersistentHeader 提供了更高的定制性,可以使用它来创建任何种类的滑动持续可见的头部组件,不仅仅是应用栏。
为什么重复造轮子
不知道你是否疑惑,已经有了ListView 和 GridView 这种处理列表和网格布局的高级小部件,为什么还要SliverList,SliverGrid呢。
对于更复杂的滚动布局需求,比如自定义滚动动画、滚动时的动态布局变化或者是在同一个滚动视图中混合使用不同类型的内容布局(例如列表和网格的组合),ListView 和 GridView 的功能可能就显得不够灵活和强大。
SliverList 和 SliverGrid 作为 Sliver 家族的一部分,它们提供了更高的灵活性和控制能力来构建复杂的滚动布局。通过使用 Slivers,开发者可以创建高度定制化的滚动效果和布局,这些在使用 ListView 和 GridView 时很难或无法实现。
具体复杂的滚动场景包括:
- 动态头部: 如在滚动时改变大小的头部或导航栏。
- 混合布局: 在同一个滚动视图中混合使用列表、网格、固定头部等不同的布局。
- 复杂的交互效果: 如滚动视图内部的元素在滚动时出现或消失的动态效果。
额外补充
直接在 ScrollView(比如 SingleChildScrollView)中嵌入 ListView 是不推荐的,因为这会导致两个滚动视图互相冲突,理想的做法是使用 SliverList 或者将 ListView 的 shrinkWrap
属性设置为 true,让 ListView 的大小自适应其内容,但这仍可能带来性能问题。