通知的NotificationListener和我們之前寫的事件的Listener一樣,都是功能性的組件,而且也都是從子節點順著widget樹向上冒泡,不同的是,事件的Listener不可以被終止,但是通知的NotificationListener是可以被終止的。 是否終止根據Notificatio... ...
如需轉載,請註明出處:Flutter學習筆記(35)--通知Notification
通知的NotificationListener和我們之前寫的事件的Listener一樣,都是功能性的組件,而且也都是從子節點順著widget樹向上冒泡,不同的是,事件的Listener不可以被終止,但是通知的NotificationListener是可以被終止的。
是否終止根據NotificationListener的返回值來決定。
說一下我個人的理解:
通知Notification的發送是通過disPatch進行分發的,就好像Android裡面的事件分發,當NotificationListener監聽到了通知事件,這時候會走到其onNotification回調中,根據回調中的返回值類型(true還是false)來決定是否還繼續向父親節點發送通知。
返回true就是繼續分發,返回false就是終止分發,返回false就意味著上層節點的NotificationListener就不會接收到通知事件了。
舉個例子就是:
兩層NotificationListener嵌套,子節點的NotificationListener返回true,那麼父親節點的NotificationListener可以接收到通知事件,反之如果返回false,那麼父親節點的NotificationListener就不會接收到通知事件了。
下麵看一下demo示例:
demo就是簡單的發送通知,監聽到通知事件後改變text的內容。
1.創建一個事件通知類,要繼承Notification,它其實就是一個數據載體,在裡面定義通知數據的類型和內容。
import 'package:flutter/material.dart'; class MyNotification extends Notification{ String notificationStr; MyNotification(this.notificationStr); }
2.NotificationListener的使用和通知事件的分發
import 'package:flutter/material.dart'; import 'package:study_app/util/MyNotification.dart'; class NotificationDemo extends StatefulWidget { @override State<StatefulWidget> createState() { return _NotificationDemoState(); } } class _NotificationDemoState extends State { String _notificationData = 'default_data'; @override Widget build(BuildContext context) { return MaterialApp( title: 'NotificationDemo', home: new Scaffold( appBar: AppBar( title: Text('NotificationDemo'), ), body: NotificationListener<MyNotification>( onNotification: (notification) { setState(() { _notificationData = notification.notificationStr; }); return true; }, child: Column( children: <Widget>[ Text(_notificationData), Builder( builder: (context) { return Container( width: double.infinity, child: RaisedButton( child: Text('發送通知'), onPressed: () { MyNotification('notification_data') .dispatch(context); }), ); }, ) ], ), )), ); } }
在看書的時候,作者強調了一種錯誤的寫法,如下圖註釋的部分:
原因是通知在分發的時候,需要一個context參數,這個參數指的是Notification監聽的子widget的context,如果按照註釋部分的寫法的話,context是根widget的,這樣會導致監聽不到子widget了。
所以需要我們通過Builder構建出我們子widget的context,這裡需要特別註意一下。
最後看一下效果截圖:
以上!有任何疑問歡迎留言!