Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any callback to tell me when "build" function is done in Flutter?

Tags:

flutter

I have a listView in my screen. I have attached a controller to it. I am able to call my Endpoint, receive response, parse it and insert in row. ListView supposed to Scroll automatically. It does, but not in perfect way. I am always an item behind. This is my code:

@override   Widget build(BuildContext context) {     // Scroll to the most recent item     if (equationList.length > 0) {       _toEnd();     }      return new Scaffold(       appBar: new AppBar(         title: new Text(widget.title),       ),       body: EquList(equationList, _scrollController),       floatingActionButton: new FloatingActionButton(         onPressed: onFabClick,         tooltip: 'Fetch Post',         child: new Icon(isLoading ? Icons.pause : Icons.play_arrow),       ),     );   }    void _toEnd() {     _scrollController.animateTo(       _scrollController.position.maxScrollExtent,       duration: const Duration(milliseconds: 250),       curve: Curves.ease,     );   } 

The problem is, I am calling _toEnd() function before the last item inserts in to the list. So, I am looking for a callback (if there is any) that tells me build() is done. Then I call my _toEnd() function.

What is the best practice in this case?

like image 288
Hesam Avatar asked Jul 06 '18 19:07

Hesam


1 Answers

General solution

Just to clear things up, I did not expect this question to attract so much attention. Hence, I only answered for this very specific case.
As explained in another answer WidgetsBinding offers a way to add a one time post frame callback.

WidgetsBinding.instance.addPostFrameCallback((_) {   // executes after build }) 

As this callback will only be called a single time, you will want to add it every time you build:

@override Widget build(BuildContext context) {   WidgetsBinding.instance.addPostFrameCallback((_) => afterBuild);   return Container(); // widget tree }  void afterBuild() {   // executes after build is done } 

Specific (async)

Elaborating on Günter's comment:

@override Widget build(BuildContext context) {   executeAfterBuild();   return Container(); }  Future<void> executeAfterBuild() async {   // this code will get executed after the build method   // because of the way async functions are scheduled } 

There is a nice example illustrating that effect here.
Extensive information about scheduling in Dart can be found here.

like image 133
creativecreatorormaybenot Avatar answered Sep 20 '22 07:09

creativecreatorormaybenot