Flutter 自定义 NotificationListener 没有收到通知?
Flutter Custom NotificationListener not receiving Notifications?
class MyParentWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return NotificationListener<MyCustomNotification>(
child: MyChildWidget(),
onNotification: (notification) {
print("Received Notification!");
return true;
},
);
}
}
class MyChildWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text("Press to send"),
onPressed: () {
print("dispatched notification!");
MyCustomNotification()..dispatch(context);
},
);
}
}
class MyCustomNotification extends Notification {
const MyCustomNotification();
}
此 flutter 代码生成的 GUI 仅包含一个可点击的按钮,点击时会分派 MyCustomNotification
的一个实例。这会将其输出到控制台:
flutter: dispatched notification!
flutter: Received Notification!
这是元素树:
...
-> MyParentWidget
-> NotificationListener<MyCustomNotification>
-> MyChildWidget
-> FlatButton
-> Text
到目前为止,这一切都很好并且有效。如控制台所示,通知已发送和接收。但是,如果我尝试组合这些小部件,就像在同一个 StatelessWidget 中一样,既会调度又会接收事件,例如
class MyCombinedWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return NotificationListener<MyCustomNotification>(
child: FlatButton(
child: Text("Press to send"),
onPressed: () {
print("dispatched notification!");
MyCustomNotification()..dispatch(context);
},
),
onNotification: (notification) {
print("Received Notification!");
return true;
},
);
}
}
(即将 MyChildWidget 的构建 return 的内容粘贴到实例化的位置)。这不再有效,即使小部件树几乎完全相同:
...
-> MyCombinedWidget
-> NotificationListener<MyCustomNotification>
-> FlatButton
-> Text
这应该行得通,对吧?通知仍然在后代中发送,并在它的祖先中被捕获。但不幸的是,这是唯一的控制台输出:
flutter: dispatched notification!
除了每次要创建通知侦听器时分开之外,是否有解决此问题的方法?更重要的是,至少对我而言:为什么会这样? 通知不再被捕获的原因是什么?
为什么会发生这种情况的答案如 docs 中所述:
A widget that listens for Notifications bubbling up the tree.
您要做的是在发送通知的同一级别接收通知。
当它们分开时它起作用,因为 child 具有不同的上下文,而在第二个代码片段中它们具有相同的上下文,因此您可以将按钮包装在构建器中,这可能会起作用,因为它通过了children
的新语境
class MyParentWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return NotificationListener<MyCustomNotification>(
child: MyChildWidget(),
onNotification: (notification) {
print("Received Notification!");
return true;
},
);
}
}
class MyChildWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text("Press to send"),
onPressed: () {
print("dispatched notification!");
MyCustomNotification()..dispatch(context);
},
);
}
}
class MyCustomNotification extends Notification {
const MyCustomNotification();
}
此 flutter 代码生成的 GUI 仅包含一个可点击的按钮,点击时会分派 MyCustomNotification
的一个实例。这会将其输出到控制台:
flutter: dispatched notification!
flutter: Received Notification!
这是元素树:
...
-> MyParentWidget
-> NotificationListener<MyCustomNotification>
-> MyChildWidget
-> FlatButton
-> Text
到目前为止,这一切都很好并且有效。如控制台所示,通知已发送和接收。但是,如果我尝试组合这些小部件,就像在同一个 StatelessWidget 中一样,既会调度又会接收事件,例如
class MyCombinedWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return NotificationListener<MyCustomNotification>(
child: FlatButton(
child: Text("Press to send"),
onPressed: () {
print("dispatched notification!");
MyCustomNotification()..dispatch(context);
},
),
onNotification: (notification) {
print("Received Notification!");
return true;
},
);
}
}
(即将 MyChildWidget 的构建 return 的内容粘贴到实例化的位置)。这不再有效,即使小部件树几乎完全相同:
...
-> MyCombinedWidget
-> NotificationListener<MyCustomNotification>
-> FlatButton
-> Text
这应该行得通,对吧?通知仍然在后代中发送,并在它的祖先中被捕获。但不幸的是,这是唯一的控制台输出:
flutter: dispatched notification!
除了每次要创建通知侦听器时分开之外,是否有解决此问题的方法?更重要的是,至少对我而言:为什么会这样? 通知不再被捕获的原因是什么?
为什么会发生这种情况的答案如 docs 中所述:
A widget that listens for Notifications bubbling up the tree.
您要做的是在发送通知的同一级别接收通知。
当它们分开时它起作用,因为 child 具有不同的上下文,而在第二个代码片段中它们具有相同的上下文,因此您可以将按钮包装在构建器中,这可能会起作用,因为它通过了children
的新语境