Flutter中很多地方使用了通知,如前面介紹的 Scrollable 組件,它在滑動(dòng)時(shí)就會(huì)分發(fā)滾動(dòng)通知(ScrollNotification),而 Scrollbar 正是通過監(jiān)聽 ScrollNotification 來確定滾動(dòng)條位置的。
下面是一個(gè)監(jiān)聽可滾動(dòng)組件滾動(dòng)通知的例子:
NotificationListener(
onNotification: (notification){
switch (notification.runtimeType){
case ScrollStartNotification: print("開始滾動(dòng)"); break;
case ScrollUpdateNotification: print("正在滾動(dòng)"); break;
case ScrollEndNotification: print("滾動(dòng)停止"); break;
case OverscrollNotification: print("滾動(dòng)到邊界"); break;
}
},
child: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text("$index"),);
}
),
);
上例中的滾動(dòng)通知如ScrollStartNotification、ScrollUpdateNotification等都是繼承自ScrollNotification類,不同類型的通知子類會(huì)包含不同的信息,比如ScrollUpdateNotification有一個(gè)scrollDelta屬性,它記錄了移動(dòng)的位移,其他通知屬性讀者可以自己查看SDK文檔。
上例中,我們通過NotificationListener來監(jiān)聽子ListView的滾動(dòng)通知的,NotificationListener定義如下:
class NotificationListener<T extends Notification> extends StatelessWidget {
const NotificationListener({
Key key,
required this.child,
this.onNotification,
}) : super(key: key);
...//省略無關(guān)代碼
}
我們可以看到:
NotificationListener 繼承自StatelessWidget類,所以它可以直接嵌套到 Widget 樹中。
NotificationListener 可以指定一個(gè)模板參數(shù),該模板參數(shù)類型必須是繼承自Notification;當(dāng)顯式指定模板參數(shù)時(shí),NotificationListener 便只會(huì)接收該參數(shù)類型的通知。舉個(gè)例子,如果我們將上例子代碼改為:
//指定監(jiān)聽通知的類型為滾動(dòng)結(jié)束通知(ScrollEndNotification)
NotificationListener<ScrollEndNotification>(
onNotification: (notification){
//只會(huì)在滾動(dòng)結(jié)束時(shí)才會(huì)觸發(fā)此回調(diào)
print(notification);
},
child: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text("$index"),);
}
),
);
上面代碼運(yùn)行后便只會(huì)在滾動(dòng)結(jié)束時(shí)在控制臺(tái)打印出通知的信息。
onNotification回調(diào)為通知處理回調(diào),其函數(shù)簽名如下:
typedef NotificationListenerCallback<T extends Notification> = bool Function(T notification);
它的返回值類型為布爾值,當(dāng)返回值為true時(shí),阻止冒泡,其父級Widget將再也收不到該通知;當(dāng)返回值為false 時(shí)繼續(xù)向上冒泡通知。
Flutter的UI框架實(shí)現(xiàn)中,除了在可滾動(dòng)組件在滾動(dòng)過程中會(huì)發(fā)出ScrollNotification之外,還有一些其他的通知,如SizeChangedLayoutNotification、KeepAliveNotification 、LayoutChangedNotification等,F(xiàn)lutter正是通過這種通知機(jī)制來使父元素可以在一些特定時(shí)機(jī)來做一些事情