Reputation: 287
How to sync scroll two SingleChildScrollView widgets ?
new Positioned(
child: new SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: new Scale()
),
),
new Positioned(
child: new SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: new chart()
)
)
I need those two widgets to have exactly same scroll position ( both have same width and can be scrolled only horizontally ). It must sync after user action and when changed in code.
Upvotes: 4
Views: 4142
Reputation: 51
I was just facing the same problem, and there's now an official package for that: linked_scroll_controller (https://pub.dev/packages/linked_scroll_controller).
Using that package, you just have to create a master LinkedScrollControllerGroup(https://pub.dev/documentation/linked_scroll_controller/latest/linked_scroll_controller/LinkedScrollControllerGroup-class.html) to keep track of the scroll offset and it'll then provide you separate ScrollControllers (kept in sync) via LinkedScrollControllerGroup.addAndGet()(https://pub.dev/documentation/linked_scroll_controller/latest/linked_scroll_controller/LinkedScrollControllerGroup/addAndGet.html).
Upvotes: 0
Reputation: 731
like xster said, you have to use scrollcontroller on one scrollview and notification Listener on another scrollview, here is the code.
class StackO extends StatefulWidget {
// const stack({Key key}) : super(key: key);
@override
_StackOState createState() => _StackOState();
}
class _StackOState extends State<StackO> {
ScrollController _scrollController = new ScrollController();
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
new Positioned(
child: new SingleChildScrollView(
controller: _scrollController,
scrollDirection: Axis.horizontal,
child: new Scale() // your widgets,
),
),
new Positioned(
child: new NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
print('scrolling.... ${scrollInfo.metrics.pixels}');
_scrollController.jumpTo(scrollInfo.metrics.pixels);
return false;
},
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: new chart() // your widgets,
),
),
),
],
),
);
}
}
Upvotes: 6
Reputation: 6667
For input, you control them via a ScrollController passed in as a constructor parameter.
For output, you can use a NotificationListener to listen to movements on one and then use the ScrollController to sync them together.
You can either listen to something like https://docs.flutter.io/flutter/widgets/UserScrollNotification-class.html to keep them tightly bound or wait for https://docs.flutter.io/flutter/widgets/ScrollEndNotification-class.html and then call https://docs.flutter.io/flutter/widgets/ScrollController/animateTo.html on the ScrollController.
Upvotes: 2