Search code examples
flutterflutter-navigation

Flutter delayed function called twice


I have a launcher screen where I check do I have specific data or not. Depending on the result I show different screens

 void main() => runApp(MyApp());


 class MyApp extends StatelessWidget {
   @override
    Widget build(BuildContext context) {
    return MaterialApp(
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: LauncherScreen()
  );
 }
}


 class LauncherScreen extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 print("build, build");
 Future.delayed(new Duration(milliseconds: 2000), () {
  LocalData localData = LocalData();
  localData.getCity().then((city) {
    if (city != null) {
      Const.city = city;
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => Home()),
      );
    } else {
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => SelectCities()),
      );
    }
  });
});
return Container(
    width: double.infinity,
    height: double.infinity,
     color: Color(GoEngColors.violet));
 }
}

My LauncherScreen called twice and as a result, I see my Home or Select city screen appears twice.

What is the reason of such behaviour and how to solve it? Thanks.


Solution

  • The build method can be called multiple times, so it's not the right place to call initialization processes. You should convert your widget to StatefulWidget (Alt + Enter on Android Studio) and call your Future.delayed from initState(). Like this:

    class LauncherScreen extends StatefulWidget {
      @override
      _LauncherScreenState createState() => _LauncherScreenState();
    }
    
    class _LauncherScreenState extends State<LauncherScreen> {
    
      @override
      void initState() {
        super.initState();
        print("build, build");
        Future.delayed(new Duration(milliseconds: 2000), () {
          LocalData localData = LocalData();
          localData.getCity().then((city) {
            if (city != null) {
              Const.city = city;
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => Home()),
              );
            } else {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => SelectCities()),
              );
            }
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {    
        return Container(width: double.infinity, height: double.infinity, color: Color(GoEngColors.violet));
      }
    }