ScrollController not attached to any scroll views

前端 未结 11 1167
难免孤独
难免孤独 2021-01-17 07:22

I\'m using CustomScrollView, and providing it with a controller. ScrollController works, I even added a listener to it and print out the position of the scroll view.

相关标签:
11条回答
  • 2021-01-17 08:01

    This sometimes happens when you are attempting to bind a ScrollController to a widget that doesn't actually exist (yet). So it attempts to bind, but there is no ListView/ScrollView to bind to. Say you have this code:

    Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Expanded(
          flex: 8,
          child: Container(
            child: ListView.builder(
              controller: scrollController,
              itemCount: messages.length,
              itemBuilder: (context, index) {
                return MessageTile(message: messages[index]);
              }),
            ),
         ),
     ]),
    

    Here we are building a ListView dynamically. Since we never declared this ListView before, the scrollController does not have anything to bind to. But this can easily be fixed:

    // first declare the ListView and ScrollController

    final scrollController = ScrollController(initialScrollOffset: 0);
    ListView list = ListView.builder(
      controller: scrollController,
      itemCount: messages.length,
      itemBuilder: (context, index) {
        return MessageTile(message: messages[index]);
      }
    );
    

    // then inside your build function just reference the already built list

    Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Expanded(
          flex: 8,
          child: Container(
             child: list,
          ),
        ),
      ]),
    
    0 讨论(0)
  • 2021-01-17 08:03

    @carlosx2 answer is correct but if someone wonder where to put WigetsBinding. So here it is.

    @override
    void initState(){
      super.initState();
      WidgetsBinding.instance.addPostFrameCallback((_){
        //write or call your logic
        //code will run when widget rendering complete
      });
    }
    
    0 讨论(0)
  • 2021-01-17 08:04

    Use setState() method to bind to a scroll related widget (your listview etc.)

    setState(() {
        topicsScrollController.animateTo(....);
    });
    
    0 讨论(0)
  • 2021-01-17 08:05

    Check if the scrollController is attached to a scroll view by using its hasClients property first.

    if (_scrollController.hasClients) 
        _scrollController.jumpTo(50.0);
    
    0 讨论(0)
  • 2021-01-17 08:09

    I found working solution, but frankly the method is not best practice, I suppose. In my case controller.jumpTo() was called before it was attached to any scroll view. In order to solve problem I delayed some milliseconds and then call .jumpTo(), because build will be called and controller will be attached to any scroll view.

    Future.delayed(Duration(milliseconds: <some time, ex: 100>), () {
             _scrollController.jumpTo(50.0);
            });
    

    I full agree that it is bad solution, but It can solve problem.

    0 讨论(0)
提交回复
热议问题