【问题标题】:Event when ScrollController get attached附加 ScrollController 时的事件
【发布时间】:2023-04-06 04:58:01
【问题描述】:

一旦获得有关最大滚动范围的信息,我将尝试显示一个小部件。如果我将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,当此值更改时(当控制器连接时)我无处调用 setState
所以我的问题: 有没有一个地方可以在ScrollController 附加到可滚动小部件时收到通知?或者有更好的方法吗?

【问题讨论】:

  • 为什么在构建过程中需要这些信息?你永远做不到。如build 重置ScrollController.positions
  • @RémiRousselet 我只想在可以向下滚动视图的情况下在屏幕底部显示某种阴影。所以我需要知道当前滚动位置和最大滚动范围来检查我相信。
  • 您可以使用CustomScrollView 中的自定义条子来完成此操作。条子不需要滚动。 SliverAppBar 就是一个很好的例子。它甚至还有取决于滚动是否有阴影的概念。
  • @RémiRousselet 明天我将深入研究定制条子。感谢您的信息!
  • @RémiRousselet 我查看了SliverAppBar 实现以及与之相关的其他碎片。与我尝试做的相比,它看起来非常复杂。我想我不完全理解在构建阴影时条子将在哪里得到它的范围。如果不是所有的东西都完成了,它怎么能做到这一点?

标签: dart flutter


【解决方案1】:

如果可滚动是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)明确定义了滚动控制器时才有效。

【讨论】:

    猜你喜欢
    • 2021-12-19
    • 2019-02-09
    • 2019-02-06
    • 2021-08-12
    • 2019-02-28
    • 2019-07-30
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多