【Flutter学习】事件处理与通知之通知(Notification)
⼀,概述
Notification是Flutter中⼀个重要的机制,在Widget树中,每⼀个节点都可以分发通知,通知会沿着当前节点(context)向上传递,所有⽗节点都可以通过NotificationListener来监听通知,Flutter中称这种通知由⼦向⽗的传递为“通知冒泡”(Notification Bubbling),这个和⽤户触摸事件冒泡是相似的,但有⼀点不同:通知冒泡可以中⽌,但⽤户触摸事件不⾏。
Flutter中很多地⽅使⽤了通知,如可滚动(Scrollable) Widget中滑动时就会分发ScrollNotification,⽽Scrollbar正是通过监听ScrollNotification来确定滚动条位置的。除了ScrollNotification,Flutter中还有SizeChangedLayoutNotification、KeepAliveNotification 、LayoutChangedNotification等。下⾯是⼀个监听Scrollable Widget滚动通知的例⼦:
NotificationListener(
onNotification: (notification){
//print(notification);
switch (notification.runtimeType){
case ScrollStartNotification: print("开始滚动"); break;
case ScrollUpdateNotification: print("正在滚动"); break;
case ScrollEndNotification: print("滚动停⽌"); break;
case OverscrollNotification: print("滚动到边界"); break;
}
},
child: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text("$index"),);
}
)
,
);
上例中的滚动通知如ScrollStartNotification、ScrollUpdateNotification等都是继承⾃ScrollNotification类,不同类型的通知⼦类会包含不同的信息,⽐如ScrollUpdateNotification有⼀个scrollDelta属性,它记录了移动的位移,其它通知属性读者可以⾃⼰查看SDK⽂档。
⼆,⾃定义通知
除了Flutter内部通知,我们也可以⾃定义通知,下⾯我们看看如何实现⾃定义通知:
定义⼀个通知类,要继承⾃Notification类;
class TestNotification extends Notification {
TestNotification({
@unt,
});
final int count;
}
⼦节点发送通知。
new RaisedButton(
textColor: Colors.black,
child: new Center(
child: new Text('点击传递随机数给上层Widget'),
),
onPressed: () {
new TestNotification(count: new Random().nextInt(100)).dispatch(key.currentContext);
})
⽗节点使⽤NotificationListener进⾏监听⼦节点发出的通知,并作出响应
new NotificationListener(
onNotification: (TestNotification n) {
scaffoldStateKey.currentState.showSnackBar(new SnackBar(content: new Text('随机数:${n.count}')));
return true;
},
child: new TestAPage(
key: key,
))
Notification有⼀个dispatch(context)⽅法,它是⽤于分发通知的,我们说过context实际上就是操作Element的⼀个接⼝,它与Element树上的节点是对应的,通知会从context对应的Element节点向上冒泡。
⽰例
下⾯我们看⼀个完整的例⼦:
class NotificationRoute extends StatefulWidget {
@override
NotificationRouteState createState() {
return new NotificationRouteState();
}
}
class NotificationRouteState extends State<NotificationRoute> {
String _msg="";
@override
flutter sdk
Widget build(BuildContext context) {
//监听通知
return NotificationListener<MyNotification>(
onNotification: (notification) {
setState(() {
_msg+=notification.msg+" ";
});
},
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// RaisedButton(
// onPressed: () => MyNotification("Hi").dispatch(context),
// child: Text("Send Notification"),
// ),
Builder(
builder: (context) {
return RaisedButton(
//按钮点击时分发通知
onPressed: () => MyNotification("Hi").dispatch(context),
child: Text("Send Notification"),
)
;
},
),
Text(_msg)
],
),
),
);
}
}
class MyNotification extends Notification {
MyNotification(this.msg);
final String msg;
}
上⾯代码中,我们每点⼀次按钮就会分发⼀个MyNotification类型的通知,我们在Widget根上监听通知,收到通知后我们将通知通过Text显⽰在屏幕上。
注意:代码中注释的部分是不能正常⼯作的,因为这个context是根Context,⽽NotificationListener是监听的⼦树,所以我们通过Builder来构建RaisedButton,来获得按钮位置的context。
运⾏效果如下:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论