Flutter 监听ListView的冒泡通知

561 阅读2分钟

最近写一个类似imessage的滑动列表,结果效果很差劲,弃坑了。不过,过程中学到了许许多多更深入的关于框架内部的知识,还是值的。那些内容太复杂,所以今天挑一个简单的ListView的通知类型讲讲。

如何捕获ListView冒泡的通知

使用NotificationListener

    NotificationListener(
          onNotification: (notification) {
            print(notification.runtimeType);
            return true;
          },
          child: ListView(
          ......
          )
     )

onNotification的返回值表示事件是否继续向上冒泡,详情见源码。

通知的类型

  1. ScrollStartNotification

dragDetails(类型为DragStartDetails):可以获得初次接触屏幕时指针的具体位置信息(以屏幕左上为原点)

metrics:该属性是关于滑动列表的一些内容,比如pixel可以获得滑动了多少像素,所有的ScrollNotification的子类都有这个属性。

context属性可以获得NotificationListener的element,可用于计算组件距离屏幕顶部的高度。

  1. ScrollUpdateNotification

scrollDelta:该属性包含了滑动距离和滑动方向。视窗上滑的时候输出负值,视窗下滑的时候输出正值,其实就是计算相较于滑动起始位置的变化量。

同样,也有一个类型为DragUpdateDetails的dragDetails属性(这个类型和GestureDetector的是一样的),通过这个属性的delta变量可以获得滑动距离distance,滑动向量direction(具体是:以手指落点为原点,如果手指垂直上滑,那么角度为Pi/2,返回值为3.14/2 = 1.57,同时,如果滑动距离很小,这个值为0.0),即scrollDelta更像是对该属性进行处理后生成的数据。

  1. ScrollEndNotification

DragEndDetials类型的dragDetails

velocity属性输出本次滑动事件结束后的滑动速度,分横轴和纵轴两个方向的速度。

  1. UserScrollNotification

direction:这个属性和上面的有些不同,返回值有三种

视窗上滑返回ScrollDirection.forward

视窗下滑返回ScrollDirection.reverse

视窗停止滑动返回ScrollDirection.idle,因为滑动有个Simulation来模拟手指放开时的继续滚动,所以屏幕还在滚动的时候并不是返回这个值。

  1. OverScrollNotification

dragDetails,velocity两个属性不在赘述。

overscroll:返回值为到达边界后,手势继续滑动超出的像素,可以猜一猜RefreshIndicator 是不是用这个属性实现的刷新。

结尾

吹水了一篇文章,也应该放弃死磕滑动列表了,毕竟磕得不明不白,头破血流。