一旦我有关于最大滚动范围的信息,我试图显示一个小部件。如果将ScrollController实例分配给可滚动小部件的controller属性,则可以找到该数字。

我的问题是在构建过程中ScrollController附加到了可滚动小部件,因此在第一次构建之前我无法使用最大滚动范围数。因此,我想做的是在第一个版本中显示一个空的Container,然后用我实际想要的小部件切换该空的Container。像这样:

    _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,并且当此值更改时(连接 Controller 时),在任何地方都无法调用setState
所以我的问题是:有什么地方可以在ScrollController附加到可滚动小部件时得到通知?还是有更好的方法呢?

最佳答案

如果滚动条是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);
}

子项必须为extends ChangeNotifier并具有update方法:
void update(ScrollMetrics metrics) {
  assert(metrics != null);
  _lastMetrics = metrics; // Save the metrics.
  notifyListeners();
}

仅当已为可滚动对象(widget.child)明确定义了滚动 Controller 时,所有这些方法才有效。

10-06 15:38