附加到多个滚动视图的 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 postion
在ScrollController
中的实现,它是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的主要内容,如果未能解决你的问题,请参考以下文章
同一视图上的多个手势(从可滚动视图中拖出视图)无法正常工作?
UITableView 上的水平滚动正在改变 UIPageControl 的位置,该 UIPageControl 附加到 TableView 单元格内的滚动视图