附加到多个滚动视图的 ScrollController

Posted

技术标签:

【中文标题】附加到多个滚动视图的 ScrollController【英文标题】:ScrollController attached to multiple scroll views 【发布时间】:2019-02-09 18:03:01 【问题描述】:

我有一个带有孩子的有状态小部件

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

【问题讨论】:

在示例中,一次只显示一个 ListView。他们在网页浏览中 【参考方案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),
      ],
    );
  

【讨论】:

@Dharman 感谢您的信息!我不认为这是重复的,因为这个问题是关于 TrackingScrollController 的具体行为(无论如何我都无法标记它),所以我更新了我的答案以更好地适应这个问题。【参考方案2】:

您是否获取_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;
 

【讨论】:

【参考方案3】:

TrackingScrollController 仅负责生成 initialScrollOffset,正如您所料,只是构建时的初始偏移量

TrackingScrollController 只是为每个 ListView 创建一个 ScrollPositions 的映射,并监听其中的每一个以进行更改,并将其存储为新的初始滚动位置,以便在下一个 ListView 呈现时使用。

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

至于例外:

flutter:抛出另一个异常:ScrollController 附加到多个滚动视图。

当您使用 get controller.positon 时会抛出此错误,即您只能在仅附加一个位置时使用此 get .

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

【讨论】:

我希望它能保持多个滚动视图同步。滚动一个,它们都一起滚动。

以上是关于附加到多个滚动视图的 ScrollController的主要内容,如果未能解决你的问题,请参考以下文章

ScrollController 未附加到任何滚动视图

如何附加滚动视图委托方法?

同一视图上的多个手势(从可滚动视图中拖出视图)无法正常工作?

UITableView 上的水平滚动正在改变 UIPageControl 的位置,该 UIPageControl 附加到 TableView 单元格内的滚动视图

如何使 UIView 高度等于其子视图的附加高度,以便它可以轻松滚动到最后

重新加载uitableview后滚动表格视图