- 一、CustomScrollView
- 二、SliverAppBar
- 三、在 CustomScrollView 中使用 SliverAppBar
- 四、在 CustomScrollView 中使用 SliverList
- 五、最终效果:
- 五、完整代码
一、CustomScrollView
Flutter cookbook 地址:https://flutter-io.cn/docs/cookbook/lists/floating-app-bar.html
默认场景下,Scalfold 的导航栏都是固定写死的,如果要做一些交互性或者是沉浸式的交互比较困难
Flutter 提供了 CustomScrollView
来帮助实现跟随列表滑动发生一些变化的 AppBar 效果
CustomScrollView
本身继承自 ScrollView
,构造函数比较简单:
const CustomScrollView({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
Key center,
double anchor = 0.0,
double cacheExtent,
this.slivers = const <Widget>[],
int semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
})
其中 slivers
用来承载内容,本身是一个 List<Widget>
类型
二、SliverAppBar
SliverAppBar
在 app_bar.dart
中是单独实现的一个 statefulWidget,从它的注释中可以看出,是专门服务于 CustomScrollView
的
/// A material design app bar that integrates with a [CustomScrollView].
本身 SliverAppBar
支持的属性和 AppBar 支持的属性差不多,SliverAppBar 因为需要跟随 ScrollView 的一些操作,属性会多一些。
const SliverAppBar({
Key key,
this.leading,
this.automaticallyImplyLeading = true,
this.title,
this.actions,
this.flexibleSpace,
this.bottom,
this.elevation,
this.forceElevated = false,
this.backgroundColor,
this.brightness,
this.iconTheme,
this.actionsIconTheme,
this.textTheme,
this.primary = true,
this.centerTitle,
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.expandedHeight,
this.floating = false,
this.pinned = false,
this.snap = false,
this.shape,
})
1、floating 属性
floating
属性说认真的 我看了好久才发现有什么区别,主要的区别在列表下滑时的表现上:
如果 floating=false
,当列表往下滑动时,会先将列表内容滚动到顶部,然后再将 SliverAppBar 浮动出现
如果 floating=true
,当列表往下滑动时,会先将 SliverAppBar 浮动出现(与列表是否滚动到顶部无关),然后再继续列表的滑动
下面的 gif 可以说明问题
1) floating = ture
2)floating = false
2、pinned 属性
pinned
属性能够决定是否将导航栏部分固定
如果固定的话,滑动的时候就不会完全消失 AppBar(这也是业务中经常需求的场景)
pinned = false
是默认行为,也就是上面的场景,整个 AppBar 会随着列表的滚动完全消失在视野中
1)pinned = true
三、在 CustomScrollView 中使用 SliverAppBar
下面 SliverAppBar
实现中,除了标题、背景色之外,更多的加了一个 flexibleSpace
属性,然后借助 Row+Expanded
的 flex 特性,放置了一张自适应的图片。
SliverAppBar(
title: Text('CustomScrollView'),
backgroundColor: Colors.pink,
// https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_pinned.mp4
floating: true,
snap: false,
pinned: false,
expandedHeight: 200,
actions: <Widget>[
Container(
margin: EdgeInsets.only(right: 16),
child: Icon(Icons.list),
),
],
leading: Icon(Icons.home),
flexibleSpace: Row(
children: <Widget>[
Expanded(
child: Image.network(IMAGE_SRC, fit: BoxFit.cover),
)
],
),
)
效果:
四、在 CustomScrollView 中使用 SliverList
SliverList
就是一个 List Widget,只不过在整个实现上,需要指定一个 delegate,比如通过 SliverChildDelegate
进行列表的构建
const SliverList({
Key key,
@required SliverChildDelegate delegate,
})
使用 SliverList
构建列表:
SliverList(
delegate: SliverChildBuilderDelegate(
_builder,
childCount: _list.length,
),
)
builder 的实现:
builder 的实现和使用 List.builder 没什么区别,不过多介绍,这里简单返回一个 ListTile 即可
Widget _builder(context, index) {
return ListTile(title: Text(_list[index]));
}
五、最终效果: