最近写一个类似imessage的滑动列表,结果效果很差劲,弃坑了。不过,过程中学到了许许多多更深入的关于框架内部的知识,还是值的。那些内容太复杂,所以今天挑一个简单的ListView的通知类型讲讲。
如何捕获ListView冒泡的通知
使用NotificationListener
NotificationListener(
onNotification: (notification) {
print(notification.runtimeType);
return true;
},
child: ListView(
......
)
)
onNotification的返回值表示事件是否继续向上冒泡,详情见源码。
通知的类型
-
ScrollStartNotification
dragDetails(类型为DragStartDetails):可以获得初次接触屏幕时指针的具体位置信息(以屏幕左上为原点)
metrics:该属性是关于滑动列表的一些内容,比如pixel可以获得滑动了多少像素,所有的ScrollNotification的子类都有这个属性。
context属性可以获得NotificationListener的element,可用于计算组件距离屏幕顶部的高度。
-
ScrollUpdateNotification
scrollDelta:该属性包含了滑动距离和滑动方向。视窗上滑的时候输出负值,视窗下滑的时候输出正值,其实就是计算相较于滑动起始位置的变化量。
同样,也有一个类型为DragUpdateDetails的dragDetails属性(这个类型和GestureDetector的是一样的),通过这个属性的delta变量可以获得滑动距离distance,滑动向量direction(具体是:以手指落点为原点,如果手指垂直上滑,那么角度为Pi/2,返回值为3.14/2 = 1.57,同时,如果滑动距离很小,这个值为0.0),即scrollDelta更像是对该属性进行处理后生成的数据。
-
ScrollEndNotification
DragEndDetials类型的dragDetails
velocity属性输出本次滑动事件结束后的滑动速度,分横轴和纵轴两个方向的速度。
-
UserScrollNotification
direction:这个属性和上面的有些不同,返回值有三种
视窗上滑返回ScrollDirection.forward
视窗下滑返回ScrollDirection.reverse
视窗停止滑动返回ScrollDirection.idle,因为滑动有个Simulation来模拟手指放开时的继续滚动,所以屏幕还在滚动的时候并不是返回这个值。
-
OverScrollNotification
dragDetails,velocity两个属性不在赘述。
overscroll:返回值为到达边界后,手势继续滑动超出的像素,可以猜一猜RefreshIndicator 是不是用这个属性实现的刷新。
结尾
吹水了一篇文章,也应该放弃死磕滑动列表了,毕竟磕得不明不白,头破血流。