为什么在使用futureBuilder时多次调用getRoute()函数?

时间:2019-11-05 14:01:52

标签: flutter dart

使用FutureBuilder时,为什么至少要两次调用getRoute()函数?这里的userInfoDao是我的本地存储,我从那里检索一个标志,该标志指示用户是否已经登录,并基于该用户被路由到登录页面还是活动页面。即使将我路由到活动页面,也会调用getRoute(),因此activitesPage的initState被称为Multiple。任何有关此问题的信息,将不胜感激。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(HomePage());
}

class HomePage extends StatefulWidget {

  HomePage();

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  UserInfoDao userInfoDao;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    userInfoDao = new UserInfoDao();
    NotificationOperations();

  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return MaterialApp(
            theme: new ThemeData(
                backgroundColor: Colors.blue, primaryColor: Colors.blue),
            initialRoute: snapshot.data,
            onGenerateRoute: RouteGenerator.generateRoute,
          );
        } else {
          return new Center(
            child: new CircularProgressIndicator(),
          );
        }
      },
      future: getRoute(),
    );
  }

  Future getRoute() async {
    print("main");
    bool flag = await userInfoDao.getValue("loggedIn");
    if (flag != null) {
      if (flag == true) {
        return '/activitiesPage';
      } else
        return '/loginPage';
    }
    return '/loginPage';
  }
}

2 个答案:

答案 0 :(得分:0)

您应将Future对象存储在State中:

class _HomePageState extends State<HomePage> {
  UserInfoDao userInfoDao;
  Future future;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    userInfoDao = new UserInfoDao();
    NotificationOperations();
    future = getRoute();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return MaterialApp(
            theme: new ThemeData(
                backgroundColor: Colors.blue, primaryColor: Colors.blue),
            initialRoute: snapshot.data,
            onGenerateRoute: RouteGenerator.generateRoute,
          );
        } else {
          return new Center(
            child: new CircularProgressIndicator(),
          );
        }
      },
      future: future,
    );
  }

  Future getRoute() async {
    print("main");
    bool flag = await userInfoDao.getValue("loggedIn").then((flag){});
    if (flag != null) {
      if (flag == true) {
        return '/activitiesPage';
      } else
        return '/loginPage';
    }
    return '/loginPage';
  }
}

来自FutureBuilder docs

  

将来一定要早一些,例如中   State.initState,State.didUpdateConfig或   State.didChangeDependencies。不得在   构造状态时调用State.build或StatelessWidget.build方法   FutureBuilder。

答案 1 :(得分:0)

尝试runOnce()here中的方法AsyncMemoizer

记住安装异步:2.4.0或higher