1
votes

I'm working on a widget that consists of several scrolling widgets (list views and a custom widget). When I scroll any of those list views the custom widget must be scrolled as well. Just to be clear the custom widget isn't actually a scroll view, but a stateful widget that updates its viewport content when a scroll position of the list views is changed.

Currently I'm using a scroll controller for each list and listener to sync the positions by calling jumpTo for the other controllers. But this seems a clumsy way to achieve what I need.

ScrollController exposes the interface to control multiple positions, and because behind the scene it's jumpTo method just calls jumpTo for each ScrollPosition object in positions list, I hoped that there is a way to utilize this for synchronization of multiple scroll views by sharing the same controller. And it seems I'm not the only one who had the same idea (ScrollController attached to multiple scroll views). But the only recommendation I could find is to use a controller per scroll view, which I already do.

Clearly I'm not completely understand how to work with scroll views in Flutter. So my questions are the following. What is the purpose of positions in the ScrollController? What is the design decision behind it and how to use it properly.

1

1 Answers

0
votes

If you want to use a single scrollController for many scrollable widgets(ListView,Gridview,etc) the scrollController save each ScrollView in a Iterable so if you want to jumpTo you need to use the argument called positions which is a Iterable<ScrollPosition> type. Somethin like this:

final _scrollController = ScrollController();

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

void _moveScroll(){
    _scrollController.animateTo(
              // ignore: invalid_use_of_protected_member
              _scrollController.positions.first.maxScrollExtent, 
              duration: Duration(milliseconds: 500), 
              curve: Curves.easeInOut);
  }