前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flutter 组件集录】Scrollbar| 8月更文挑战

【Flutter 组件集录】Scrollbar| 8月更文挑战

作者头像
张风捷特烈
发布2022-03-18 15:25:35
1.1K0
发布2022-03-18 15:25:35
举报
一、Scrollbar 的使用
1. Scrollbar 的效果

ListView 这种可滑动的组件中,默认情况没有右侧的指示器 ,这样用户在滑动中不太容易知道滑动进度。使用 Scrollbar 就可以在 右侧 出现滑动条。如下分别是在 AndroidiOS 的效果,可以看出在不同平台上,Scrollbar 的展示是有所差异的,比如圆角、高度、宽度等。这些我们都能从源码中找到根源。

从使用的角度来看,Scrollbar 非常简单,只是在 ListView 外层嵌套一下就行了。然后滑动时就会发现有滚动指示器,这看起来非常神奇。神奇的点在于: ListView 的滑动没有和 Scrollbar 有任何的直接联系, Scrollbar 竟然可以跟随 ListView 的进行滑动。

代码语言:javascript
复制
class ScrollbarDemo extends StatelessWidget {
  const ScrollbarDemo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scrollbar( //<--- tag1
      child: ListView(
          children:
              List.generate(
                60, 
                (index) => ItemBox(index: index)).toList()),
    );
  }
}

这种 可插拔 式的组合,既可以让组件间几乎没有耦合,又可以让一方随另一方进行改变。Scrollbar 虽然在使用上非常简单,但其背后的这套数据通知方案是非常值得我们去研究学习的。

2. Scrollbar 的表现属性

从下面 Scrollbar 的构造函数中可以看出,除了 child 是必传的入参,还有 8 个 参数,这里先看一下 isAlwaysShownthicknessradius 三个决定 Scrollbar 显示的属性。

代码语言:javascript
复制
Scrollbar(
   isAlwaysShown: true, // 是否一直显示
   radius: const Radius.circular(3), // 圆角半径
   thickness: 6,// 线宽
   child: ...
 );

如下左侧是 安卓平台默认显示 效果,可以看出 Scrollbar 只在滑动过程中显示出来,并且显隐时伴随 透明渐变动画 效果。如下右侧上面三个属性设置后的效果,isAlwaysShown 表示 Scrollbar 是否一直显示;radius 表示 圆角半径thickness 表示 Scrollbar 滑块的宽度。

3. Scrollbar 的尺寸区域

所有可以显示的组件都会尤其占据的位置区域,大家可以思考一下 Scrollbar 的尺寸是 包括 ListView 的整体,还是只是一个细的长条,或只是一个小滑块。通过 布局查看器 可以看出 Scrollbar 的尺寸是包括 ListView 在内的整个一大片。到这里,我们或多或少可以猜到 Scrollbar 源码在布局上的处理。

4.可交互性:interactive

如下两幅图分别是 interactive:falseinteractive:true 的效果。它的作用很明显:如果为 true 时,小滑块可以接受拖动事件,来控制列表的滑动。在移动端默认为 false

5.回调通知:notificationPredicate

notificationPredicate 是一个回调函数,会将 ScrollNotification 对象回调给使用者,并且返回 bool 值决定是否显示 Scrollbar

代码语言:javascript
复制
@override
Widget build(BuildContext context) {
  return Scrollbar(
    notificationPredicate: _notificationPredicate,
    child: ListView(
        children:
            List.generate(60, (index) => ItemBox(index: index)).toList()),
  );
}

bool _notificationPredicate(ScrollNotification notification) {
  print('----$notification---------');
  return true;
}
6.滑动控制器:controller

如果你只为 ListView 指定了 controller 属性,那么 Scrollbar 则会报错。你必须保证两者有同一个滑动控制器。通过 滑动控制器 我们可以监听列表的滑动,以及控制滑动。

除此之外,showTrackOnHoverhoverThickness 两个属性顾名思义是悬浮时的效果,这一般只在 非移动端 设备上有效果,另外,目前 ListView 在桌面端中默认自带 Scrollbar

到这里 Scrollbar 所有的属性用法就已经介绍完毕。下面简单地看一下 Scrollbar 的源码实现,不止于是知道怎么用,还能对它的内部机制有一点了解,源码中的一些逻辑处理,这或许在某些场景中能对你产生帮助,多了解一些总没什么坏处。知其然,知其所以然,你把握的才够通透

二、Scrollbar 源码简看
1. Scrollbar 类定义

从下面可以看出 Scrollbar 是一个 StatefulWidget ,通过 _ScrollbarState 状态类构建组件。

下面是 _ScrollbarState 的全部代码,通过如果是 iOS 平台,则构建 CupertinoScrollbar,否则构建 _MaterialScrollbar

这是 _ScrollbarState 的全部源码,不过我从这里看不出 Scrollbar 是 StatefulWidget 的必要性。不知你有什么见解。

2. 滑动事件的监听和滑块的移动

CupertinoScrollbar_MaterialScrollbar 都是继承自 RawScrollbar ,也就是说它们的底层逻辑是一样的,只不过根据平台进行一定的适配。

RawScrollbarState 构建组件代码中可以看到,使用了 NotificationListener 监听 ScrollNotification 通知,执行 _handleScrollNotification 方法。如果不了解 NotificationListener 组件,可以看一下第一篇

_handleScrollNotification 中有一些比较核心的逻辑,其中 notificationPredicate 回调会先触发,如果该函数返回 false ,也就意味着_handleScrollNotification 返回 false ,下面的逻辑不会被执行。这也是为什么返回 false 时,滑块不显示的原因。下面会执行透明渐变动画,以及根据 notification 信息更新 scrollbarPainter 画板,这是滑块可以跟随列表滑动最核心的处理。

3.滑块的绘制

RawScrollbarState#build 方法的最后,是通过前景画板 foregroundPainter 进行绘制,child 为传入的 ListView,这也是为什么 Scrollbar 的尺寸区域是整个一片的原因。

绘制的画板是 ScrollbarPainter ,在状态初始化时被创建。

ScrollbarPainter 继承自 ChangeNotifier ,并实现 CustomPainter ,也就是说它既是可监听对象,又是画板,也就说明它自己可以通知进行画板重绘,使用这里 ScrollbarPainter 是以成员变量的方式声明的,在需要更新时,自己执行更新。这也很值得我们学习借鉴,源码是最好的老师。至于具体的绘制逻辑,就不说了,有兴趣的自己看看。

Scrollbar 组件的使用方式到这里就介绍完毕,那本文到这里就结束了,谢谢观看,明天见~

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Scrollbar 的使用
  • 1. Scrollbar 的效果
  • 2. Scrollbar 的表现属性
  • 3. Scrollbar 的尺寸区域
  • 4.可交互性:interactive
  • 5.回调通知:notificationPredicate
  • 6.滑动控制器:controller
  • 二、Scrollbar 源码简看
    • 1. Scrollbar 类定义
      • 2. 滑动事件的监听和滑块的移动
        • 3.滑块的绘制
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档