ScrollController附加到多个滚动视图

时间:2018-09-04 16:47:01

标签: flutter

我有一个有状态的小部件,其中有孩子

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有不合理的期望吗?

3 个答案:

答案 0 :(得分:1)

获取_trackingScrollController滚动位置吗?如果是这样,您将得到错误。

下面是get postionScrollController的实现,它是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 :(得分:1)

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

TrackingScrollController只是为每个ListView创建一个ScrollPositions映射,并侦听其中的每个变化,这些变化将其作为呈现下一个ListView时要使用的新的初始滚动位置。

与预期的行为相比,您的预期行为是什么?如果可以的话,请提供有关您的目标和实施的更多信息。

至于例外:

  

颤振:引发了另一个异常:ScrollController附加到多个滚动视图。

当您使用 get controller.positon while 时,会抛出多个位置,即只有在附加了单位置。

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

答案 2 :(得分:1)

请参阅阿什顿·托马斯(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),
      ],
    );
  }
}