Flutter教学目录持续更新中
Github源代码持续更新中
1.NotificationListener介绍
widget通知监听
2.NotificationListener属性
- child:widget
- onNotification:NotificationListenerCallback<Notification>,返回值true表示消费掉当前通知不再向上一级NotificationListener传递通知,false则会再向上一级NotificationListener传递通知;这里需要注意的是通知是由下而上去传递的,所以才会称作冒泡通知
3.ScrollNotification
ScrollNotification是一个抽象类,它的子类还有:
- ScrollStartNotification:滑动开始通知
- ScrollUpdateNotification:滑动中通知,滑动过程中会一直回调
- ScrollEndNotification:滑动结束通知
- OverscrollNotification:滑动位置未改变通知,这个一般只有在滑动到列表边界才会回调,且需要设置不可越界,即physics为ClampingScrollPhysics,这里要注意安卓默认是这样,但是ios平台默认是弹性边界
- UserScrollNotification:用户滑动通知,这个跟ScrollUpdateNotification的区别是他指挥有滑动开始后以及滑动结束后回调
4.Notification.ScrollMetrics属性
- pixels:当前绝对位置
- atEdge:是否在顶部或底部
- axis:垂直或水平滚动
- axisDirection:滚动方向描述是down还是up,这个受列表reverse影响,正序就是down倒序就是up,并不代表列表是上滑还是下滑
- extentAfter:视口底部距离列表底部有多大
- extentBefore:视口顶部距离列表顶部有多大
- extentInside:视口范围内的列表长度
- maxScrollExtent:最大滚动距离,列表长度-视口长度
- minScrollExtent:最小滚动距离
- viewportDimension:沿滚动方向视口的长度
- outOfRange:是否越过边界
4.使用
_myChild() {
return ListView.builder(
itemBuilder: (context, index) => ListTile(title: Text('item $index')),
itemCount: 30,
reverse: true,
// physics: BouncingScrollPhysics(),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('NotificationListener'),
),
body: NotificationListener<ScrollNotification>(
onNotification: (notification) {
ScrollMetrics metrics = notification.metrics;
print('ScrollNotification####################');
print('pixels = ${metrics.pixels}');
print('atEdge = ${metrics.atEdge}');
print('axis = ${metrics.axis}');
print('axisDirection = ${metrics.axisDirection}');
print('extentAfter = ${metrics.extentAfter}');
print('extentBefore = ${metrics.extentBefore}');
print('extentInside = ${metrics.extentInside}');
print('maxScrollExtent = ${metrics.maxScrollExtent}');
print('minScrollExtent = ${metrics.minScrollExtent}');
print('viewportDimension = ${metrics.viewportDimension}');
print('outOfRange = ${metrics.outOfRange}');
print('ScrollNotification####################');
return false;
},
child: NotificationListener<ScrollUpdateNotification>(
onNotification: (notification) {
print('ScrollUpdateNotification####################');
return false;
},
child: NotificationListener<OverscrollNotification>(
onNotification: (notification) {
print('OverscrollNotification####################');
return false;
},
child: NotificationListener<ScrollStartNotification>(
onNotification: (notification) {
print('ScrollStartNotification####################');
return false;
},
child: NotificationListener<ScrollEndNotification>(
onNotification: (notification) {
print('ScrollEndNotification####################');
return false;
},
child: _myChild(),
),
),
),
),
),
);
}
image.png
5.系统提供的其他Notification
Notification是所有通知监听的顶级父类,它的子类有:
- LayoutChangedNotification:这是一个空实现子类,他的子类有ScrollNotification,SizeChangedLayoutNotification
- SizeChangedLayoutNotification:这是一个空实现子类,一般不会用到
- DraggableScrollableNotification:DraggableScrollableSheet的拖拽通知,这个后面再介绍
- OverscrollIndicatorNotification:这是滑动指示器的通知监听,例如Scrollbar,需要注意的是这个只有在滑动到头部或者尾部才会回调,而且滑动布局也需要是不可越界的,即physics为ClampingScrollPhysics
这里的代码就在上期Flutter(82):Scroll组件之Scrollbar上修改一下:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scrollbar'),
),
body: NotificationListener<OverscrollIndicatorNotification>(
onNotification: (notification) {
//滑动指示器是否在头部 true在前端,false在末端
print('${notification.leading}');
return true;
},
child: Scrollbar(
radius: Radius.circular(10),
thickness: 10,
child: ListView.builder(
itemBuilder: (context, index) {
return ListTile(
title: Text('item $index'),
);
},
itemCount: 30,
),
),
),
);
}
- KeepAliveNotification:这个留意过列表复用的源码的话,例如ListView,就会知道addAutomaticKeepAlives就是使用这个来保存状态的
6.自定义Notification
这里我们做个简单的演示
body: NotificationListener<_CustomNotification>(
onNotification: (notification) {
print('1 ${notification.msg}');
return true;
},
child: NotificationListener<_CustomNotification>(
onNotification: (notification) {
print('2 ${notification.msg}');
return true;
},
child: Builder(builder: (context) {
return RaisedButton(
onPressed: () {
_CustomNotification('点击了Button').dispatch(context);
},
child: Text('RaisedButton'),
);
}),
),
),
class _CustomNotification extends Notification {
_CustomNotification(this.msg);
final String msg;
}
image.png
这里在2级NotificationListener处消费掉当前的通知了,所以不再向1级NotificationListener传递通知了,如果将2级NotificationListener处设置为false,则会传递
image.png下一节:DraggableScrollableSheet、DraggableScrollableNotification
网友评论