Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【FlutterUnit周边】SliverPersistentHeader使用指南

【FlutterUnit周边】SliverPersistentHeader使用指南

作者头像
张风捷特烈
发布于 2023-09-01 05:05:34
发布于 2023-09-01 05:05:34
1.1K00
代码可运行
举报
运行总次数:0
代码可运行
零、前言

如果你进入过FlutterUnit,那么主页中头部的Tap栏你应该印象深刻。 如下效果: 在上滑时Tap栏会逐渐变矮,直到最小值。下拉到顶时变矮的Tap栏会逐渐变高,直到最大值 FlutterUnit本身主页比较复杂,本文就来写一个最简实践,用最少的代码来实现这个效果。 本文的主人公是SliverPersistentHeader,来一起看一下它的用法。

上滑效果

下拉效果

一、项目初始
1. 程序入口

在 main 函数中使用SystemChrome.setSystemUIOverlayStyle让状态栏变透明 测试 demo 的核心组件在 SliverPersistentHeaderDemo

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void main() {
  //设置透明 状态栏
  SystemUiOverlayStyle style = SystemUiOverlayStyle(statusBarColor: Colors.transparent);
  SystemChrome.setSystemUIOverlayStyle(style);
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        debugShowCheckedModeBanner: false,
        theme: ThemeData( primarySwatch: Colors.blue  ),
        home: Scaffold(
          body: SliverPersistentHeaderDemo(),
        ));
  }
}

2.构建色彩列表

我们要构建的是比较复杂的滑动效果, 可以使用CustomScrollView,其中slivers接收Sliver家族组件的列表。CustomScrollView不是本文的主人公,这里不多说,以后会有专篇。 如下: _buildSliverList负责构建SliverList,其中颜色的item组件的构建交由_buildColorItem 。我建议大家可以把构建的粒度细分一下,不要什么都塞一块,这样看起来会比较清晰。

色彩列表

色彩列表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class SliverPersistentHeaderDemo extends StatelessWidget {
	// 色彩数据
  final List<Color> data = List.generate(24, (i) => Color(0xFFFF00FF - 24*i));

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
        slivers: <Widget>[
          // TODO 添加 bar
          _buildSliverList()
        ],
    );
  }

  // 构建颜色列表
  Widget _buildSliverList() =>
      SliverList(
        delegate: SliverChildBuilderDelegate(
                (_, int index) => _buildColorItem(data[index]),
            childCount: data.length),
      );

	// 构建颜色列表item
  Widget _buildColorItem(Color color) =>
      Card(
        child: Container(
          alignment: Alignment.center,
          width: 100,
          height: 60,
          color: color,
          child: Text(
            colorString(color),
            style: const TextStyle(
                color: Colors.white,
                shadows: [
                  Shadow(color: Colors.black,
                      offset: Offset(.5, .5),
                      blurRadius: 2)
                ]),
          ),
        ),
      );
  
	// 颜色转换为文字
  String colorString(Color color) =>
      "#${color.value.toRadixString(16).padLeft(8, '0').toUpperCase()}";
}

这样初始的demo就搭建好了,下面来看看SliverPersistentHeader的用法吧


二、认识 SliverPersistentHeader
1.SliverPersistentHeader属性一览

属性名

类型

默认值

介绍

delegate

SliverPersistentHeaderDelegate

required

组件构建代理

pinned

bool

false

是否固定

floating

bool

false

是否浮动


2.SliverPersistentHeaderDelegate的使用

估计很多人看到XXXDelegate就有种劝退的感觉。先别怕,看看它是什么。 可以看到它是抽象类,说明需要实现一些抽象方法,而一般抽象方法都会为我们回调一些有价值的东西 查看他的族谱,发现没有可以使用的子类,那么想使用它,二话不说,先写个他的子类。

现在写一个UnitPersistentHeaderDelegate实现一下SliverPersistentHeaderDelegate, 可以看到有下面四个需要实现的方法: build,maxExtent,minExtent,shouldRebuild

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UnitPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    print(
        "=====shrinkOffset:$shrinkOffset======overlapsContent:$overlapsContent====");
    final String info =
        'shrinkOffset:${shrinkOffset.toStringAsFixed(1)}'
        '\noverlapsContent:$overlapsContent';
    return Container(
      alignment: Alignment.center,
      color: Colors.orangeAccent,
      child: Text(
        info,
        style: TextStyle(fontSize: 20, color: Colors.white),
      ),
    );
  }
  @override
  double get maxExtent => 120;
  
  @override
  double get minExtent => 80;
  
  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) =>
      false;
}

先简单实现一下使用上面定义的UnitPersistentHeaderDelegate查看效果: 可以看到上面的build方法的作用就是构建组件,shrinkOffset为偏移量 头部栏组件开始完全展开maxExtent高度,随着列表上滑而上滑,可以从日志里看出最大上滑高度为maxExtent,这是默认pinned=false,floating=false的滑动效果。

上滑测试

下拉测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    //英雄所见...
    return CustomScrollView(
      slivers: <Widget>[
        _buildPersistentHeader(), //<-- 在列表上方创建PersistentHeader
        _buildSliverList()
      ],
    );
  }
	
  // 使用UnitPersistentHeaderDelegate创建PersistentHeader
  Widget _buildPersistentHeader() => SliverPersistentHeader(
      delegate: UnitPersistentHeaderDelegate());

3.SliverPersistentHeader的pinned与floating属性

下面开始试验:

pinned_true_floating_false

pinned_true_floating_true

上滑:顶部会留出minExtent的高度,不再随上滑而减小

上滑:顶部会留出minExtent的高度,不再随上滑而减小

下拉:直到滑到顶端时,剩余空间才会展开

下拉: 任意位置下拉时, 剩余空间会展开


下面开始试验:

pinned_false_floating_false

pinned_false_floating_true

上滑: 顶部会滑出

上滑:顶部会滑出

下拉:直到滑到顶端时,顶部才会展开

下拉: 任意位置下拉时, 空间会展开


三、使用 SliverPersistentHeader
1. 封装PersistentHeaderBuilder

上面使用起来比较麻烦,可以自定义一个PersistentHeaderBuilder来简化构建 使用builder属性,将创建的逻辑移交到使用时,可以回调一些有价值的数据,比如偏移量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class PersistentHeaderBuilder extends SliverPersistentHeaderDelegate {
  final double max;
  final double min;
  final Widget Function(BuildContext context, double offset) builder;

  PersistentHeaderBuilder(
      {this.max = 120, this.min = 80, @required this.builder})
      : assert(max >= min && builder != null);

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return builder(context, shrinkOffset);
  }

  @override
  double get maxExtent => max;

  @override
  double get minExtent => min;

  @override
  bool shouldRebuild(covariant PersistentHeaderBuilder oldDelegate) =>
      max != oldDelegate.max ||
      min != oldDelegate.min ||
      builder != oldDelegate.builder;
}

2.使用PersistentHeaderBuilder
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  Widget _buildPersistentHeader() => SliverPersistentHeader(
      pinned: true,
      floating: false,
      delegate: PersistentHeaderBuilder(builder: (ctx, offset) => Container(
        alignment: Alignment.center,
        color: Colors.orangeAccent,
        child: Text(
          "shrinkOffset:${offset.toStringAsFixed(1)}",
          style: TextStyle(fontSize: 20, color: Colors.white),
        ),
      )));

3.多个SliverPersistentHeader的使用

你也可以根据offset来进行一些变换处理。 多个SliverPersistentHeader是可以共存的,如下

上滑

下拉

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Widget _buildPersistentHeader2() => SliverPersistentHeader(
    pinned: false,
    floating: false,
    delegate: PersistentHeaderBuilder(
        max: 100,
        builder: (ctx, offset) => Container(
              transform: Matrix4.rotationZ(offset / 120 * pi / 2),
              alignment: Alignment.center,
              color: Colors.blue,
              child: Text(
                "shrinkOffset:${offset.toStringAsFixed(1)}",
                style: TextStyle(fontSize: 20, color: Colors.white),
              ),
            )));

SliverPersistentHeader基本用法就是这样,你可以基于此实现很多有意思的滑动效果 最后欢迎关注我的开源项目 FlutterUnit,FlutterUnit相关的周边文章会陆续更新,其中包括一些Flutter组件的用法,或一些FlutterUnit实现的细节,FlutterUnit的重大更新等,欢迎持续关注。

@张风捷特烈 2020.10.25 未允禁转 ~ END ~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-10-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Flutter 3.13 组件更新 | 欢迎 Slivers 体系 5 位新成员
在 Flutter 3.13 更新中,增加了 5 位新的 Sliver 相关组件,用于滑动视口中,完成特定功能。这篇文章将介绍一下它们的作用和使用场景。
张风捷特烈
2023/09/01
1.1K0
Flutter 3.13 组件更新 | 欢迎 Slivers 体系 5 位新成员
【Flutter 专题】52 图解可折叠状态栏
和尚以前在学习滑动冲突时曾用过 Sliver 系列的 Widget,和尚这次尝试用 SliverAppBar 来处理;
阿策小和尚
2019/08/12
1.4K0
【Flutter 专题】52 图解可折叠状态栏
Flutter入门指北(Part 8)之Sliver 组件及NestedScrollView
在上节最后,给小伙伴们展示了 SliveGrid 和 SliverFixedExtentList 的用法,基本上和 GridView 和 ListView 的用法差不多,所以这边就不多讲这两个部件了。
陈宇明
2020/12/16
2.3K0
Flutter 首页必用组件NestedScrollView
老孟导读:昨天Flutter 1.17版本重磅发布,新的版本主要是优化性能、修复bug,有人觉得此版本毫无亮点,但也从另一方面体现了Flutter目前针对移动端已经较为完善,想了解具体内容,文末有链接,如果你想升级到最新版本,建议慎重,有些人升级后项目无法运行。
老孟Flutter
2020/09/11
4.4K0
Flutter | Slivers 系列
CustomScrollView:一个滚动的容器,改组件不接受任何 child,但是你可以直接提供 Slivers 已创建各种滚动效果,例如页面中有多个可滑动的列表,如 Appbar, 列表,网格,等这种就可以直接使用 SliverAppBar,SliverList 和 SliverGrid
345
2022/02/11
1.5K0
Flutter | Slivers 系列
flutter系列之:使用SliverList和SliverGird
在上一篇文章我们讲解SliverAppBar的时候有提到过,Sliver的组件一般都用在CustomScrollView中。除了SliverAppBar之外,我们还可以为CustomScrollView添加List或者Grid来实现更加复杂的组合效果。
程序那些事
2023/02/13
1K0
Flutter跨平台移动端开发丨SingleChildScrollView、ListView......
SingleChildScrollView 类似 Android 中的 scrollview ,且同样的只可包含有一个子元素
码脑
2019/05/25
8.9K0
Flutter可滑动组件
移动端数据量比较大时,一般都是通过列表来进行展示的,比如商品数据、聊天列表、通信录、朋友圈等。
白白白小艾
2022/03/24
7.3K0
flutter中对列表的性能优化
下面是一些使用ListView对象呈现列表列表的代码,内部列表的shrinkWrap值设置为 true。shrinkWrap强行评估整个内部列表,允许它请求有限的高度,而不是通常的ListView对象高度,即无穷大!
徐建国
2021/11/30
3.7K0
flutter中对列表的性能优化
flutter3.27-dymall基于Flutter3+Getx抖音App直播短视频商城
带来一款春节期间自研的Flutter3.27+Dart3.6跨平台仿抖音App短视频+直播商城+聊天项目。
andy2018
2025/02/07
1370
flutter3.27-dymall基于Flutter3+Getx抖音App直播短视频商城
Flutter | 滚动组件,ListView,GridVIew等
当组件内容超过当前显示视口(ViewPort)时,如果没有特殊处理,Flutter 就会提示 Overflow 错误,为此,Flutter 提供了多种可滚动组件,用于显示列表和长布局;
345
2022/02/11
8.8K0
Flutter | 滚动组件,ListView,GridVIew等
实现点击"换一批"来切换内容,flutter之CustomScrollView【flutter20个实例之八】
一、老套路,先看样式 左图是我业务中的样式,右图是下方源码展示样式(复制可直接运行,无额外组件引入) 二、讲解 1.涉及组件 首先,没有一个单一组件来实现这个效果 实现这个效果涉及以下组件: AppB
sinnoo
2020/11/13
1.5K0
实现点击"换一批"来切换内容,flutter之CustomScrollView【flutter20个实例之八】
Flutter开发实战分析-animation_demo瞎复写总结
以下代码基本参考于 flutter_gallery中的animation_demo示例。(可以结合本文看源码)
deep_sadness
2018/08/30
2.5K0
Flutter开发实战分析-animation_demo瞎复写总结
Flutter之SliverAppBar
SliverAppBar控件可以实现页面头部区域展开、折叠的效果,类似于Android中的CollapsingToolbarLayout。
老孟Flutter
2020/09/11
1.5K0
Flutter SliverAppBar全解析,你要的效果都在这了!
SliverAppBar 类似于Android中的CollapsingToolbarLayout,可以轻松实现页面头部展开、合并的效果。 与AppBar大部分的属性重合,相当于AppBar的加强版。
yechaoa
2022/06/10
3.1K0
Flutter SliverAppBar全解析,你要的效果都在这了!
如何快速提升 Flutter App 中的动画性能
观前提醒:本文假设你已经有一定的 Flutter 开发经验,对Flutter 的 Widget,RenderObject 等概念有所了解,并且知道如何开启 DevTools。
逆锋起笔
2020/12/14
1.6K0
Flutter开发-可滚动组件
当组件内容超过当前显示视口(ViewPort)时,如果没有特殊处理,Flutter则会提示Overflow错误。
码客说
2020/05/14
4.7K0
Flutter开发-可滚动组件
Flutter开发实战分析-pesto_demo解析
以下代码基本参考于 flutter_gallery中的pesto_demo示例。(可以结合本文看源码)
deep_sadness
2018/08/30
2.4K0
Flutter开发实战分析-pesto_demo解析
【Flutter 组件集录】Draggable 与 DragTarget
Draggable 顾名思义,是可拖动的组件,它继承自 StatefulWidget ,且可接受一个泛型。 构造方法有非常多的入参,其中必须传入的是 child 和 feedback 两个组件。
张风捷特烈
2022/03/18
1K0
【Flutter 组件集录】Draggable 与 DragTarget
flutter系列之:如丝般顺滑的SliverAppBar
对于一个APP来说,肯定会有一个AppBar,这个AppBar一般包含了APP的导航信息等。虽然我们可以用一个固定的组件来做为AppBar,但是这样就会丢失很多特效,比如将AppBar固定在顶部,AppBar可以在滑动的过程中进行大小变换等。
程序那些事
2023/02/24
1.9K0
flutter系列之:如丝般顺滑的SliverAppBar
相关推荐
Flutter 3.13 组件更新 | 欢迎 Slivers 体系 5 位新成员
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验