【问题标题】:Run async function in the body of a scaffold在脚手架主体中运行异步函数
【发布时间】:2020-09-19 20:46:39
【问题描述】:

我想根据一个名为 isAdmin 的布尔变量来决定屏幕上显示的内容。此字段的值是从 Firestore 中获取的。

这是我目前得到的:

Future<bool> isUserAnAdmin() async {
    var snap = await Firestore.instance
        .collection("Users")
        .document(UserSingleton().fireUser.uid)
        .get();
    UserSingleton().user = User.fromJson(snap.data);
    return UserSingleton().user.isAdmin;
  }

@override
  Widget build(BuildContext context) {
    return Scaffold(
        extendBodyBehindAppBar: true,
        appBar: AppBar(
          title: Text("hemlp"),
          actions: [
            Padding(
              padding: const EdgeInsets.only(right: 15),
              child: GestureDetector(
                child: Icon(Icons.exit_to_app),
                onTap: () async => await Auth.logoutUser().then(
                    (value) => Navigator.pushNamed(context, '/SignInPage')),
              ),
            )
          ],
        ),
        body: isUserAnAdmin() == true ? AdminPage() : PatientPage());
  }

问题是我总是被路由到 PatientPage(),而不管 isAdmin 的值如何。我怀疑这是因为它没有等待 isUserAnAdmin() 返回的值。我以为我可以等待 isUserAnAdmin(),但我不能在 Scaffold 的主体中使用 await。

我认为我可以通过这样做来解决问题:

body: isUserAnAdmin().then((value) {
          value == true ? AdminPage() : PatientPage(); 
        })

但我收到一条错误消息:

The argument type 'Future<Null>' can't be assigned to the parameter type 'Widget'.

知道如何解决这个问题吗?

【问题讨论】:

    标签: flutter google-cloud-firestore async-await


    【解决方案1】:

    为了使用Future,你需要使用await。但通常在小部件中,我们使用 FutureBuilder 代替:

     Widget build(BuildContext context) {
        return Scaffold(
            extendBodyBehindAppBar: true,
            appBar: AppBar(
              title: Text("hemlp"),
              actions: [
                Padding(
                  padding: const EdgeInsets.only(right: 15),
                  child: GestureDetector(
                    child: Icon(Icons.exit_to_app),
                    onTap: () async => await Auth.logoutUser().then(
                        (value) => Navigator.pushNamed(context, '/SignInPage')),
                  ),
                )
              ],
            ),
            body: FutureBuilder<bool>(
              future: isUserAnAdmin(),
    builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
              if (snapshot.hasData) {
                 if(snapshot.data == true) {
                   return AdminPage();
                 } else {
                   return PatientPage();
              } else {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
            }
    );
      }
    

    【讨论】:

      【解决方案2】:

      您应该在正文中使用 FutureBuilder。 这将调用您的异步函数并在结果准备好时更新。

      【讨论】:

        【解决方案3】:

        你的身体应该使用 FutureBuilder:

        body: FutureBuilder<bool>(
          future: isUserAnAdmin(),
          builder: (context, data) {
            if (data.hasData && data.data) {
              return AdminPage();
            } else {
              return PatientPage();
            }
          },
        )
        

        【讨论】:

          猜你喜欢
          • 2022-11-16
          • 1970-01-01
          • 2020-07-26
          • 2021-06-28
          • 2020-07-07
          • 1970-01-01
          • 1970-01-01
          • 2021-09-23
          • 2015-05-12
          相关资源
          最近更新 更多