【问题标题】:FLUTTER scroll controller is throwing stack overflow error when using jumpTo method使用 jumpTo 方法时,FLUTTER 滚动控制器抛出堆栈溢出错误
【发布时间】:2019-02-27 09:53:14
【问题描述】:

我正在尝试同步移动两个卷轴, 我设法用一个而不是另一个来移动它们。

我使用controllerjumpTo方法来设置对方的offset。 但如果我触摸另一个滚动条,我会收到 stack overflow 错误。

在我的示例(如下)中,如果我滚动浏览“MOVE”就可以了。 但是当我触摸“FOLLOW”时,它会给我一个错误,我必须重新启动应用程序。

这背后的解释是什么? 我该如何解决这个问题?

最后我想要有很多可以像这样移动的卷轴, 但我需要让“TEXT HERE”不要在它们之间移动。

下面是我的全部main.dart, 请试一试。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {


  var c1 = ScrollController(); // controller declaration
  var c2 = ScrollController();



  @override void initState() { 
    super.initState(); 
  }

  @override
  Widget build(BuildContext context) {

    print('start');

    return Scaffold(
      appBar: AppBar(
        title: new Text('data test'),
      ),

      body: new Container( //===================================
        padding: EdgeInsets.all(30),
        color: Colors.blue[100],
        height: 200,

        child: NotificationListener<ScrollNotification>(
          child: Column(
            children: <Widget>[
              Text('SOME TEXT HERE'),
              SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                controller: c1, // KONTROLER
                child: Container(height: 50, color: Colors.green[100], child: Row( children: <Widget>[
                  Container(width: 100,child: Text('+MOOOVE        -')),
                  Container(width: 100,child: Text('-MOOOVE        -')),
                  Container(width: 100,child: Text('-MOOOVE        -')),
                  Container(width: 100,child: Text('*MOOOVE        *')),
                  Container(width: 100,child: Text('-MOOOVE        -')),
                  Container(width: 100,child: Text('-MOOOVE        -')),
                  Container(width: 100,child: Text('-MOOOVE        +')),

                ],),)
              ),
              Text('ANOTHER TEXT HERE'),
              SingleChildScrollView(
                      scrollDirection: Axis.horizontal,
                controller: c2, // KONTROLER
                child: Container(height: 50, color: Colors.red[100], child: Row(children: <Widget>[

                  Container(width: 100,child: Text('+        FOLLOW-')),
                  Container(width: 100,child: Text('-        FOLLOW-')),
                  Container(width: 100,child: Text('-        FOLLOW-')),
                  Container(width: 100,child: Text('*        FOLLOW*')),
                  Container(width: 100,child: Text('-        FOLLOW-')),
                  Container(width: 100,child: Text('-        FOLLOW-')),
                  Container(width: 100,child: Text('-        FOLLOW+')),
                ],),)
              ),
          ]),


          onNotification: (ScrollNotification scrollinfo) {  // HEY!! LISTEN!!

            c2.jumpTo( c1.offset ); // c1 is controlling c2's offset

            print('OFFSET--'+c1.offset.toInt().toString()+"--"+c2.offset.toInt().toString());
          },
        )
      ), // ===================
    );
  }
}

谢谢。

【问题讨论】:

  • 问题是因为您将ScrollNotificationScrollController 结合使用,jumpTo 会触发ScrollNotification,而后者又会触发jumpTo,这就是您收到 SO 错误的原因。您应该检查滚动时触发的ScrollController.addListener :)。
  • 你能给我一个如何修复我上面的代码的例子吗?我把.addListener放在哪里?我还应该使用onNotification吗?
  • @danypata 或者也许,是否有可能有 1 个 controller 来控制两个卷轴?
  • 我尝试使用TrackingScrollController,但它根本不起作用。
  • 我给了你一个工作代码,不是吗?它使用了两个列表,您可以滚动其中任何一个,另一个列表紧随其后

标签: scroll dart controller flutter synchronization


【解决方案1】:

所以我建议使用ScrollController(docs here)。这是一段关于如何使用它们的代码。

import 'package:flutter/cupertino.dart';
class MyHomePage extends StatefulWidget {
     @override
     _MyHomePageState createState() => _MyHomePageState();
 }

 class _MyHomePageState extends State<MyHomePage> {
      ScrollController firstScroll = ScrollController();
      ScrollController secondScrollController = ScrollController();

      @override
      void initState() {
         super.initState();
         firstScroll.addListener(() {
        //THIS IS called when scroll is triggered, but it might be called for other events
            secondScrollController
               .jumpTo(firstScroll.offset); // THIS will sync the scroll;
         });
       }

       @override
       Widget build(BuildContext context) {
         return Container(
            child: Column(
              children: <Widget>[
                SingleChildScrollView(
                 // this is the first scroll
                    scrollDirection: Axis.horizontal,
                    controller: firstScroll, // THIS IS THE FIRST SCROLL CONTROLLER
                    child: Container(
                       //TODO: add your content here here
                    ),
                ),
                SingleChildScrollView(
                   scrollDirection: Axis.horizontal,
                   controller: secondScrollController,
                   // HERE YOU SET THE SECOND CONTROLLER
                   child: Container(
                      //TODO: add your content here
                   ),
                 )
            ],
        ),
     );
  }
}

请注意,代码只是关于如何将滚动从一个滚动小部件转发到另一个的 sn-p。然后,您可以在滚动侦听器主体中实现您想要的任何逻辑。

【讨论】:

  • 这正是我所做的,但如果我移动第二个卷轴,第一个卷轴将不会跟随。并且如果我在第二个滚动条上添加一个侦听器,那么两个滚动条将相互拖动,因为它们会不断覆盖它们的偏移量,并且它会像地狱一样结结巴巴。
  • 嘿,克里斯,你找到了答案吗?我面临着类似的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 1970-01-01
相关资源
最近更新 更多