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.
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,
),
),
]),
@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
});
}
Use setState() method to bind to a scroll related widget (your listview etc.)
setState(() {
topicsScrollController.animateTo(....);
});
Check if the scrollController is attached to a scroll view by using its hasClients property first.
if (_scrollController.hasClients)
_scrollController.jumpTo(50.0);
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.