我有一个有状态的小部件,其中有孩子
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有不合理的期望吗?
答案 0 :(得分:1)
您获取了_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;
}
答案 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),
],
);
}
}