Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

flutter - ScrollController attached to multiple scroll views

I have a stateful widget with children as such

final _scrollController = TrackingScrollController();

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

This seems to match the pattern shown here https://docs.flutter.io/flutter/widgets/TrackingScrollController-class.html

However, when I scroll one list, the others are not synced, and I get this error for every frame

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

Any ideas as to what I'm doing wrong? Do I have unreasonable expectations of TrackingScrollController?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Please see Ashton Thomas' explanation for why TrackingScrollController doesn't work for this use case. To achieve the behavior you described, you can use a new package released by Google: linked_scroll_controller.

First, add this package to your pubspec.yaml:

dependencies:
  linked_scroll_controller: ^0.1.2
  // ...

And then integrate it into your code like this:

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),
      ],
    );
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...