ScrollController附着时发生的事件 [英] Event when ScrollController get attached
问题描述
一旦我获得有关最大滚动范围的信息,我将尝试显示一个小部件。如果将 ScrollController
的实例分配给可滚动小部件的 controller
属性,则可以找到该数字。
I'm trying to display a widget once I have info about the max scroll extent. I can find that number if I assign an instance of ScrollController
to the controller
property of a scrollable widget.
我的问题是 ScrollController
在构建期间会附加到可滚动的小部件,所以我不能使用第一次构建之前的最大滚动范围数。因此,我想做的是在第一个版本中显示一个空的 Container
,然后将该空的 Container
切换为我真正想要的小部件。像这样:
My problem is that the ScrollController
gets attached to the scrollable widget during the build, so I can not use the max scroll extent number before the first build. Thus what I was trying to do is display an empty Container
in the first build and then switch that empty Container
with the widget I actually want. Something like this:
_scrollController.positions.length == 0 ? new Container() : new Align(
alignment: Alignment.center,
child: new Container(
width: constraints.maxWidth,
height: 50.0,
color: Colors.black,
)
)
现在这不起作用当然是因为 _scrollController.positions.length
开头将为0,并且当此值更改时,我无处调用 setState
(
所以我的问题:是否有一个地方可以在 ScrollController
通知我附加到可滚动的小部件?还是有更好的方法呢?
Now this does not work of course because _scrollController.positions.length
will be 0 at the beginning and nowhere do I call setState
when this value changes (when the controller gets attached).
So my question: Is there a place where I can get notified whenever the ScrollController
gets attached to a scrollable widget? Or is there a better approach for this?
推荐答案
如果滚动条是 widget.child
。
@override
Widget build(BuildContext context) {
return new NotificationListener<ScrollNotification>(
onNotification: _handleScrollNotification,
child: widget.child,
);
}
bool _handleScrollNotification(ScrollNotification notification) {
if (notification is ScrollUpdateNotification || notification is OverscrollNotification) {
widget.child.update(notification.metrics);
}
return false;
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => afterFirstLayout(context));
}
void afterFirstLayout(BuildContext context) {
applyInitialScrollPosition();
}
void applyInitialScrollPosition() {
ScrollController scrollControler = widget.child.controller;
ScrollPosition position = scrollControler.position;
ScrollNotification notification = ScrollUpdateNotification(
metrics: FixedScrollMetrics(
minScrollExtent: position.minScrollExtent,
maxScrollExtent: position.maxScrollExtent,
pixels: position.pixels,
viewportDimension: position.viewportDimension,
axisDirection: position.axisDirection),
context: null,
scrollDelta: 0.0);
_handleScrollNotification(notification);
}
孩子必须扩展ChangeNotifier
并具有 update
方法:
void update(ScrollMetrics metrics) {
assert(metrics != null);
_lastMetrics = metrics; // Save the metrics.
notifyListeners();
}
所有这一切仅在为可滚动对象( widget.child)。
All this only works if a scroll controller has explicitly been defined for the scrollable (widget.child).
这篇关于ScrollController附着时发生的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!