### 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內部通知,我們也可以自定義通知,下面我們看看如何實現自定義通知:
1. 定義一個通知類,要繼承自Notification類;
```
class MyNotification extends Notification {
MyNotification(this.msg);
final String msg;
}
```
2. 分發通知。
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
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。
運行效果如下:

- 緣起
- 起步
- 移動開發技術簡介
- Flutter簡介
- 搭建Flutter開發環境
- 常見配置問題
- Dart語言簡介
- 第一個Flutter應用
- 計數器示例
- 路由管理
- 包管理
- 資源管理
- 調試Flutter APP
- Dart線程模型及異常捕獲
- 基礎Widgets
- Widget簡介
- 文本、字體樣式
- 按鈕
- 圖片和Icon
- 單選框和復選框
- 輸入框和表單
- 布局類Widgets
- 布局類Widgets簡介
- 線性布局Row、Column
- 彈性布局Flex
- 流式布局Wrap、Flow
- 層疊布局Stack、Positioned
- 容器類Widgets
- Padding
- 布局限制類容器ConstrainedBox、SizeBox
- 裝飾容器DecoratedBox
- 變換Transform
- Container容器
- Scaffold、TabBar、底部導航
- 可滾動Widgets
- 可滾動Widgets簡介
- SingleChildScrollView
- ListView
- GridView
- CustomScrollView
- 滾動監聽及控制ScrollController
- 功能型Widgets
- 導航返回攔截-WillPopScope
- 數據共享-InheritedWidget
- 主題-Theme
- 事件處理與通知
- 原始指針事件處理
- 手勢識別
- 全局事件總線
- 通知Notification
- 動畫
- Flutter動畫簡介
- 動畫結構
- 自定義路由過渡動畫
- Hero動畫
- 交錯動畫
- 自定義Widget
- 自定義Widget方法簡介
- 通過組合現有Widget實現
- 實例:TurnBox
- CustomPaint與Canvas
- 實例:圓形漸變進度條(自繪)
- 文件操作與網絡請求
- 文件操作
- Http請求-HttpClient
- Http請求-Dio package
- 實例:Http分塊下載
- WebSocket
- 使用Socket API
- Json轉Model
- 包與插件
- 開發package
- 插件開發:平臺通道簡介
- 插件開發:實現Android端API
- 插件開發:實現IOS端API
- 系統能力調用
- 國際化
- 讓App支持多語言
- 實現Localizations
- 使用Intl包
- Flutter核心原理
- Flutter UI系統
- Element和BuildContext
- RenderObject與RenderBox
- Flutter從啟動到顯示