1

I'm creating a page that has a TextField, when user enters 3+ char in it I fetch rows, from a database, that contain the inserted text. In the example I provide I simulate this by getting a List. After this a list is presented to the user, the user can tap one of the rows to go to another page.

gist example

My problem is that when I tap a row MaterialPageRoute WidgetBuilder runs twice, this is the log:

---------- onTap ----------
---------- MaterialPageRoute ----------
---------- SecondPage build ----------
---------- MaterialPageRoute ----------
---------- SecondPage build ----------

Can someone explain this behavior and also how to fix it?

Thanks.

dshukertjr
  • 15,244
  • 11
  • 57
  • 94
NCSantos
  • 31
  • 4
  • This is the desired behavior. Build can be called anytimes. You may want to see https://stackoverflow.com/questions/52249578/how-to-deal-with-unwanted-widget-build – Rémi Rousselet Oct 02 '18 at 09:18
  • A few days ago I also asked that and that was the answer. But this is also for the MaterialPageRoute WidgetBuilder? – NCSantos Oct 02 '18 at 09:57
  • Seems like so. Anyway you should not care about how many times "build" is called. In no circunstances this should have any impact on your application – Rémi Rousselet Oct 02 '18 at 10:02
  • This odd behaviors are strange to me. If I create the list in a `initState` the MaterialPageRoute WidgetBuilder is run only once. – NCSantos Oct 02 '18 at 10:11
  • @NCSantos that's correct, but then it will never update when your app re-renders. Like Remi said, you shouldn't be concerned with too many builds, the Flutter widget tree is optimized for this sort of thing. – Kirollos Morkos Oct 02 '18 at 14:58

1 Answers1

1

I have faced the same problem. This is because you didn't add any condition to FutureBuilder. So when you are using setState() it gets called for the next time.

You can solve it using a flag in Future function so that it is invoked for the first time only. Eg:

bool flag = true;
flag?FutureBuilder(
future: getData(),
builder: (BuildContext context, AsyncSnapshot snap){
  if(snap.connectionState != ConnectionState.done){
     return Center(child: CircularProgressIndicator(),);
  }else{
     return populate();
  }
},
):Container();
 Future getData()async{
    flag = false;
    return await fetchFromDatabase();
 }
Sazzadur Rahaman
  • 6,938
  • 1
  • 30
  • 52
A_Rush
  • 368
  • 3
  • 14