一尘不染

同步滚动多个可滚动小部件

flutter

简而言之:

有没有办法将多个可滚动的小部件(例如SingleSchildScrollView)同步在一起?


我只想要2个可滚动项,可以在我滚动一个时滚动另一个。

这样,我可以Stack将它们放在彼此的顶部,而后面的一个可以跟随前面的一个滚动。

或将它们放在另一组中ColumnRow以使它们分开,但仍可以通过滚动其中一个滚动来滚动。

我尝试使用,controller但似乎并没有按照我的想法做。


尝试下面的代码,例如,“ RIGHT”将在“ LEFT”的前面,如果我尝试滚动它们,则只有RIGHT会移动。那么我如何同时将它们一起移动呢?

请不要告诉我将堆栈放在a内ListView,那不是我所需要的。

class _MyHomePageState extends State<MyHomePage> {

  final ScrollController _mycontroller = new ScrollController();

  @override
  Widget build(BuildContext context) {
    body:
      Container(
        height: 100,
        child:
          Stack( children: <Widget>[
            SingleChildScrollView(
              controller: _mycontroller,
              child: Column( children: <Widget>[
                Text('LEFT            '),
                Text('LEFT            '),
                Text('LEFT            '),
                Text('LEFT            '),
                Text('LEFT            '),
                Text('LEFT            '),
              ],)
            ),
            SingleChildScrollView(
              controller: _mycontroller,
              child: Column(children: <Widget>[
                Text('          RIGHT'),
                Text('          RIGHT'),
                Text('          RIGHT'),
                Text('          RIGHT'),
                Text('          RIGHT'),
                Text('          RIGHT'),
              ],)
            ),
          ])
      )
}}

我相信之前在多个论坛中都曾问过这个问题,但没有人对此提出任何结论或解决方案。


阅读 317

收藏
2020-08-13

共1个答案

一尘不染

我使用他们的管理,以同步多个scrollables offset,利用他们ScrollNotification

这是一个粗略的代码示例:

class _MyHomePageState extends State<MyHomePage> {

  ScrollController _mycontroller1 = new ScrollController(); // make seperate controllers
  ScrollController _mycontroller2 = new ScrollController(); // for each scrollables

  @override
  Widget build(BuildContext context) {
    body:
      Container(
        height: 100,
        child: NotificationListener<ScrollNotification>( // this part right here is the key
          Stack( children: <Widget>[

            SingleChildScrollView( // this one stays at the back
              controller: _mycontroller1,
              child: Column( children: <Widget>[
                Text('LEFT            '),
                Text('LEFT            '),
                Text('LEFT            '),
                Text('LEFT            '),
                Text('LEFT            '),
                Text('LEFT            '),
              ],)
            ),
            SingleChildScrollView( // this is the one you scroll
              controller: _mycontroller2,
              child: Column(children: <Widget>[
                Text('          RIGHT'),
                Text('          RIGHT'),
                Text('          RIGHT'),
                Text('          RIGHT'),
                Text('          RIGHT'),
                Text('          RIGHT'),
              ],)
            ),
          ]),

          onNotification: (ScrollNotification scrollInfo) {  // HEY!! LISTEN!!
            // this will set controller1's offset the same as controller2's
            _mycontroller1.jumpTo(_mycontroller2.offset);

            // you can check both offsets in terminal
            print('check -- offset Left: '+_mycontroller1.offset.toInt().toString()+ ' -- offset Right: '+_mycontroller2.offset.toInt().toString()); 
          }
        )
      )
}}

基本上每个人SingleChildScrollView都有自己的controller。每个controller都有自己的offset价值观。NotificationListener<ScrollNotification>滚动滚动时,使用通知任何移动。

然后对于每个滚动手势(我相信这是一帧一帧的基础),我们可以随意添加jumpTo()命令来设置offset

干杯!!

PS。如果列表的长度不同,则偏移量将不同,并且如果尝试滚动超过其限制,则会收到堆栈溢出错误。确保添加一些异常或错误处理。(即if else等)

2020-08-13