而在android中一般是使用 AppBarLayout + CoordinatorLayout + CollapsingToolbarLayout来实现的,那么在flutter中, 这个效果该如何实现呢?
这里我们先看一个概念,叫 CustomScrollView。

CustomScrollView

官方文档是这样解释的。一个使用slivers来创建自定义滚动效果的ScrollView
CustomScrollView让你直接提供 slivers来创建不同的滚动效果,比如lists,grids 以及 expanding headers。
如果要创建一个包含 可伸展的appbar ,后面跟着list 和grid 这样的滚动视图,可以使用这三种slivers:SliverAppBarSliverAppBar 和SliverGrid
在这些slivers中的widget必须产生 RenderSliver对象。
为了控制这些滚动视图的初始滚动偏移量,可以通过 controller和他的 ScrollController.initialScrollOffset属性来设置。

下面的例子展示了 scroll view包含 flexible pinned app bar, 一个grid 和一个无限的list。

class CustomWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {    return CustomScrollView(      slivers: [        SliverAppBar(            pinned: true,            expandedHeight: 150.0,            flexibleSpace: const FlexibleSpaceBar(              title: Text('Available seats'),            ),            actions: [              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的图,两个合在一起展示了。

SliverAppBar

定义: 配套 CustomScrollView使用的material design app bar。
一个app bar由 一个 toolbar 和 其他潜在的widgets组成,比如 TabBar 和 FlexibleSpaceBar。 App bars 通常会 通过IconButtons来暴露一个或者多个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]使用:

 SliverAppBar(   expandedHeight: 150.0,   flexibleSpace: const FlexibleSpaceBar(     title: Text('Available seats'),   ),   actions: [     IconButton(       icon: const Icon(Icons.add_circle),       tooltip: 'Add new entry',       onPressed: () { /* ... */ },     ),   ] )复制代码

将这段代码放入到上面CustomScrollView的样例代码中,效果如下:

 

下面的内容主要是细致分析 SliverAppBar构造函数中 floatingsnappinned取不同的值对于交互效果的影响变化。

动画样例

App bar -- [floating]: false, [pinned]: false, [snap]: false:

 

 

现象描述:

  • 向上滑动时: AppBar 延伸区域先收起来->appbar滑出去->list滑动出去
  • 向下滑动时: list滑动回来->appbar滑回来->延伸区域滑回来

App bar -- [floating]: true, [pinned]: false, [snap]: false:

 

现象描述:

  • 向上滑动时: AppBar 延伸区域先收起来->appbar滑出去->list滑动出去
  • 向下滑动时: appbar滑回来->延伸区域滑回来->list滑回来

App bar -- [floating]: true, [pinned]: false, [snap]: true:

 

现象描述:

  • 向上滑动时: AppBar 延伸区域先收起来->appbar滑出去->list滑动出去
  • 向下滑动时: appbar滑回来->延伸区域在检测到有轻微下滑的加速度就会动画形式直接展开盖在list之上->list滑回来

App bar -- [floating]: true, [pinned]: true, [snap]: false:

 

现象描述:

  • 向上滑动时: AppBar 延伸区域先收起来->list滑动出去
  • 向下滑动时: 延伸区域滑回来->list滑回来

App bar -- [floating]: true, [pinned]: true, [snap]: true:

 

现象描述:

  • 向上滑动时: AppBar 延伸区域先收起来->list滑动出去
  • 向下滑动时: 延伸区域在检测到有轻微下滑的加速度就会动画形式直接展开盖在list之上->list滑回来

App bar with [floating]: false, [pinned]: true, [snap]: false:

 

现象描述:

  • 向上滑动时: AppBar 延伸区域先收起来->list滑动出去
  • 向下滑动时: list滑回来->延伸区域滑回来

snap属性只能在float属性为true的情况下设置.
总结下来
pinned最容易理解,是否固定appbar不滑出屏幕。
floating改变了下滑时候appbar出现优先级的顺序,appbar(以及延伸区域)出现的优先级>list的优先级。
snap要结合floating,检测到下滑的轻微加速度就会以动画形式将appbar完全展开盖在list之上。
这里留意到一个现象是在慢速持续的向下滑动时,snap的值true和false差别不大。
本文样例分支代码已上传github ,分支CustomScrollView分支。

作者:ershixiong
链接:https://juejin.im/post/5d0274846fb9a07edd2a0d4c
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. Android(安卓)Nine-patch(.9.png)小结
  3. Android点击软键盘外的区域,关闭软键盘
  4. android dex分包支持
  5. React native WebView 适配Android(安卓)和 Ios的问题
  6. Android中如何实现WebView与JavaScript的相互调用
  7. android,利用layoutParams代码动态布局空间位置
  8. Android与服务器通信——http方式通信
  9. Android(安卓)自定义View 慢慢画一个不同颜色扇形的圆,点击圆上不

随机推荐

  1. Android相机对焦问题
  2. Android类参考---Fragment
  3. Android(安卓)DataBinding使用详解
  4. Android自带的signapk.jar + .x509.pem +
  5. Android(安卓)豆瓣电影- RecyclerView
  6. Android(安卓)studio打开github上clone下
  7. Android隐藏标题栏和状态栏
  8. Android(安卓)Studio添加assets文件夹
  9. Android(安卓)Junit Test
  10. Android中怎么动态控制padding