一个ScrollController被附加到多个滚动视图上

9
我有一个带有以下子元件的有状态小部件:
final _scrollController = TrackingScrollController();

PageView(
  controller: _pageController,
  children: <Widget>[
    _ListView(controller: _scrollController),
    _ListView(controller: _scrollController),
    _ListView(controller: _scrollController),
  ],
)

这似乎符合此处所示的模式 https://docs.flutter.io/flutter/widgets/TrackingScrollController-class.html。但是,当我滚动一个列表时,其他列表不会同步,并且我会在每帧中得到以下错误:flutter: Another exception was thrown: ScrollController attached to multiple scroll views. 有什么想法是我做错了什么? 我对TrackingScrollController期望过高了吗?

1
在这个例子中,每次只显示一个ListView。因为它们都在一个PageView内。 - Rémi Rousselet
3个回答

6
请查看Ashton Thomas的解释,了解为什么TrackingScrollController不适用于此用例。要实现您描述的行为,可以使用Google发布的新软件包:linked_scroll_controller
首先,在您的pubspec.yaml中添加此软件包:
dependencies:
  linked_scroll_controller: ^0.1.2
  // ...

然后像这样将其集成到您的代码中:
class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final _pageController = PageController();

  // This group keeps track of the synchronized scroll offset.
  final _scrollControllerGroup = LinkedScrollControllerGroup();
  ScrollController _scrollController1;
  ScrollController _scrollController2;
  ScrollController _scrollController3;

  @override
  void initState() {
    super.initState();

    // Create separate ScrollControllers as you need them:
    _scrollController1 = _scrollControllerGroup.addAndGet();
    _scrollController2 = _scrollControllerGroup.addAndGet();
    _scrollController3 = _scrollControllerGroup.addAndGet();
  }

  @override
  void dispose() {
    // Don't forget to dispose all of your controllers!
    _pageController.dispose();
    _scrollController1.dispose();
    _scrollController2.dispose();
    _scrollController3.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return PageView(
      controller: _pageController,
      children: <Widget>[
        // Use controllers only once:
        ListView(controller: _scrollController1),
        ListView(controller: _scrollController2),
        ListView(controller: _scrollController3),
      ],
    );
  }
}

@Dharman 谢谢你的信息!我不认为这是一个重复的问题,因为这个问题是关于 TrackingScrollController 的具体行为(而且我也无法标记它),所以我更新了我的答案以更好地适应这个问题。 - Jonas Wanke

1

您是否正在获取_trackingScrollController滚动位置?如果是,您将会收到错误提示。

以下是ScrollControllerget position的实现,这是TrackingScrollController的基础。

ScrollPosition get position {
  assert(_positions.isNotEmpty, 'ScrollController not attached to any scroll views.');
  assert(_positions.length == 1, 'ScrollController attached to multiple scroll views.');
  return _positions.single;
 }

1

TrackingScrollController 是仅负责生成 initialScrollOffset 的控制器,正如您所期望的那样,仅在构建时是初始偏移量

TrackingScrollController 为每个 ListView 创建一个 ScrollPositions 映射,并监听每个 ListView 的更改,将其存储为下一个 ListView 渲染时要使用的新初始滚动位置。

您的预期行为与实际情况有何不同?如果可以,请提供有关您的目标和实施的更多信息。

至于异常:

flutter: Another exception was thrown: ScrollController attached to multiple scroll views.

当您使用 get controller.positon 同时 挂接多个位置时,即只能在仅挂接单个位置时使用此 get,会引发此异常。

你可能想利用 get 方法来获取 controller.positions(注意复数形式,这是可迭代的)


11
我原以为它能够保持多个滚动视图同步。在一个视图上滚动,其他视图也会跟着一起滚动。 - Luke Pighetti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接