Search code examples
androidlistviewflutterdart

Flutter error: 'ScrollController not attached to any scroll views.' on scroll


Whenever I scroll in my listview, I get this error spammed in console:

ScrollController not attached to any scroll views.
'package:flutter/src/widgets/scroll_controller.dart':
Failed assertion: line 110 pos 12: '_positions.isNotEmpty'

I've been trying to fix this all day and I'd like to have someone else take a look at it. There are more problems with this code, but right now I'm mainly interested in fixing this error.

I've tried to use Listview.builder, checking for hController.hasClients and many more small things. They didn't seem to change anything

class MyHome extends StatefulWidget {
  @override
  MyHomeState createState() => new MyHomeState();
}

class MyHomeState extends State<MyHome> with SingleTickerProviderStateMixin {
  ScrollController hController;
  ScrollController tController;
  ScrollController fController;
  ScrollController bController;

  @override
  void initState() {
    super.initState();
    hController = new ScrollController()..addListener(_scrollListener);
    tController = new ScrollController()..addListener(_scrollListener);
    fController = new ScrollController()..addListener(_scrollListener);
    bController = new ScrollController()..addListener(_scrollListener);
  }

  @override
  void dispose() {
    super.dispose();
    hController.removeListener(_scrollListener);
    tController.removeListener(_scrollListener);
    fController.removeListener(_scrollListener);
    bController.removeListener(_scrollListener);
  }
  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
        length: 4,
        child: new Scaffold(
          //Removed AppBar for readability
          body: new TabBarView(
            children: [
              new Container(// hot
                child: ListView(
                    controller: hController,
                    children: <Widget>[
                      Utils.show("hot")
                    ],
                ),
              ),
              new Container( //Trending
                child: ListView(
                  controller: tController,
                  children: <Widget>[
                    Utils.show("trending")
                  ],
                ),
              ),
              new Container( //Fresh
                child: ListView(
                  controller: fController,
                  children: <Widget>[
                    Utils.show("fresh")
                  ],
                ),
              ),
              new Container( //Best
                child: ListView(
                  controller: bController,
                  children: <Widget>[
                    Utils.show("best")
                  ],
                ),
              ),
            ],
          ),
        ));
  }
  void _scrollListener() {
    if (hController.position.extentAfter == 0.0) {
      setState(() {
        Utils.show("hot");
      });
    }else if (tController.position.extentAfter == 0.0) {
      setState(() {
        Utils.show("trending");
      });
    } else if (fController.position.extentAfter == 0.0) {
      setState(() {
        Utils.show("fresh");
      });
    } else if (bController.position.extentAfter == 0.0) {
      setState(() {
        Utils.show("best");
      });
    }
  }

}

Edit: For some clarity, the first time I posted this code, I used tController twice. This was ofcourse a mistake, but did not solve the error. The error happens when scrolling in every one of the four listviews.


Solution

  • To avoid such type of errors use the getter

    ScrollController.hasClient
    

    If this is false, then members that interact with the [ScrollPosition],such as [position], [offset], [animateTo], and [jumpTo], must not be called.

    for example:

        if (_controller.hasClients) {
          _controller.animateTo(
          ...
        }