本文多图预警,请注意在wifi下观看O(∩_∩)O~~
不少软件都有吸附顶部的效果,一图胜千言(这里偷懒,使用的是简书中的图)。 android
官方文档是这样解释的。一个使用slivers
来建立自定义滚动效果的ScrollView
。
CustomScrollView
让你直接提供 slivers
来建立不一样的滚动效果,好比lists,grids 以及 expanding headers。
若是要建立一个包含 可伸展的appbar ,后面跟着list 和grid 这样的滚动视图,可使用这三种slivers:SliverAppBar
,SliverAppBar
和SliverGrid
。
在这些slivers
中的widget必须产生 RenderSliver
对象。
为了控制这些滚动视图的初始滚动偏移量,能够经过 controller
和他的 ScrollController.initialScrollOffset
属性来设置。git
下面的例子展现了 scroll view包含 flexible pinned app bar, 一个grid 和一个无限的list。github
class CustomWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
expandedHeight: 150.0,
flexibleSpace: const FlexibleSpaceBar(
title: Text('Available seats'),
),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_circle),
tooltip: 'Add new entry',
onPressed: () {
/* ... */
},
),
]),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 20,
),
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: Text('list item $index'),
);
},
),
),
],
);
}
}
复制代码
效果图见下方SliverAppBar
的图,两个合在一块儿展现了。bash
定义: 配套 CustomScrollView
使用的material design app bar。
一个app bar由 一个 toolbar 和 其余潜在的widgets组成,好比 TabBar
和 FlexibleSpaceBar
。 App bars 一般会 经过IconButton
s来暴露一个或者多个common actions,后面也可选的跟PopupMenuButton
,能够作一些经常使用操做。
Sliver app bars 一般被用做 CustomScrollView
的第一个孩子,能够根据scroll view中其余孩子的滚动偏移量来动态调整高度。 若是要使用一个固定高度的app bar 能够看AppBar
, 用在Scaffold.appBar
这一块。
这个AppBar展现一些toolbar widgets,leading
(最左侧的按钮)、title
以及actions
,都在bottom
之上。若是flexibleSpace
widget也被指定内容了,它将会被放在 toolbar 和 bottom widget 之下。
下面这段代码能够被CustomScrollView
的[CustomScrollView.slivers]使用:app
SliverAppBar(
expandedHeight: 150.0,
flexibleSpace: const FlexibleSpaceBar(
title: Text('Available seats'),
),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_circle),
tooltip: 'Add new entry',
onPressed: () { /* ... */ },
),
]
)
复制代码
将这段代码放入到上面CustomScrollView的样例代码中,效果以下:
less
下面的内容主要是细致分析 SliverAppBar
构造函数中 floating
、snap
、pinned
取不一样的值对于交互效果的影响变化。ide
App bar -- [floating]: false, [pinned]: false, [snap]: false:
函数
App bar -- [floating]: true, [pinned]: false, [snap]: false:
flex
App bar -- [floating]: true, [pinned]: false, [snap]: true:
动画
App bar -- [floating]: true, [pinned]: true, [snap]: false:
App bar -- [floating]: true, [pinned]: true, [snap]: true:
App bar with [floating]: false, [pinned]: true, [snap]: false:
snap
属性只能在float
属性为true的状况下设置.
总结下来
pinned
最容易理解,是否固定appbar不滑出屏幕。
floating
改变了下滑时候appbar出现优先级的顺序,appbar(以及延伸区域)出现的优先级>list的优先级。
snap
要结合floating
,检测到下滑的轻微加速度就会以动画形式将appbar彻底展开盖在list之上。
这里留意到一个现象是在慢速持续的向下滑动时,snap
的值true和false差异不大。
本文样例分支代码已上传github ,分支CustomScrollView分支。
若是你以为这篇文章对你有益,还请帮忙转发和点赞,万分感谢。