Flutter Widget树中子Widget能够经过发送告诉(Notification)与父(包含祖先)Widget通信。父级组件能够经过NotificationListener
组件来监听自己关注的告诉。
可翻滚组件在翻滚时会发送ScrollNotification
类型的告诉,ScrollBar
正是经过监听翻滚告诉来完成的。经过NotificationListener
监听翻滚事情和经过ScrollController
有两个主要的不同:
- NotificationListener能够在可翻滚组件到widget树根之间任意方位监听。而
ScrollController
只能和具体的可翻滚组件相关后才能够。 - 收到翻滚事情后获得的信息不同;
NotificationListener
在收到翻滚事情时,告诉中会带着当时翻滚方位和ViewPort的一些信息,而ScrollController
只能获取当时翻滚方位。
import 'package:flutter/material.dart';
class ScrollNotificationTestRoute extends StatefulWidget {
@override
_ScrollNotificationTestRouteState createState() =>
_ScrollNotificationTestRouteState();
}
class _ScrollNotificationTestRouteState
extends State<ScrollNotificationTestRoute> {
String _progress = "0%"; //保存进展百分比
@override
Widget build(BuildContext context) {
return Scrollbar(
//进展条
// 监听翻滚告诉
child: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
double progress = notification.metrics.pixels /
notification.metrics.maxScrollExtent;
//重新构建
setState(() {
_progress = "${(progress * 100).toInt()}%";
});
print("BottomEdge: ${notification.metrics.extentAfter == 0}");
return false;
//return true; //铺开此行注释后,进展条将失效
},
child: Stack(
alignment: Alignment.center,
children: <Widget>[
ListView.builder(
itemCount: 100,
itemExtent: 50.0,
itemBuilder: (context, index) => ListTile(title: Text("$index")),
),
CircleAvatar(
//显现进展百分比
radius: 30.0,
child: Text(_progress),
backgroundColor: Colors.black54,
)
],
),
),
);
}
}
在接收到翻滚事情时,参数类型为ScrollNotification
,它包含一个metrics
特点,它的类型是ScrollMetrics
,该特点包含当时ViewPort及翻滚方位等信息:
-
pixels
:当时翻滚方位。 -
maxScrollExtent
:最大可翻滚长度。 -
extentBefore
:滑出ViewPort顶部的长度;此示例中相当于顶部滑出屏幕上方的列表长度。 -
extentInside
:ViewPort内部长度;此示例中屏幕显现的列表部分的长度。 -
extentAfter
:列表中未滑入ViewPort部分的长度;此示例中列表底部未显现到屏幕规模部分的长度。 -
atEdge
:是否滑到了可翻滚组件的鸿沟(此示例中相当于列表顶或底部)。