【问题标题】:How do I wait for an async function to finish executing before rendering a widget in Flutter如何在 Flutter 中渲染小部件之前等待异步函数完成执行
【发布时间】:2019-11-06 11:01:14
【问题描述】:

在我的 main.dart 文件中,我想检查用户是否已登录,以便将他引导到相应的屏幕。我正在使用 SharedPrefence 从 Firebase 存储用户详细信息。 如何告诉我的函数等到我的 SharedPreference 异步函数完成执行才能呈现适当的小部件。

下面是我的代码

  Widget _gotoHomeScreen() {
  AuthService.getuserPrefEmail().then((email) {
  print(email);
  AuthService.email = email;
  if (email == null) {
    return LoginScreen();
  } else {
    AuthService.uid = email;
    return HomeMenuScreen();
  }
});

}

【问题讨论】:

    标签: firebase flutter dart async-await


    【解决方案1】:

    您不必等待构建,您应该构建一些东西,向用户显示应用正在加载某些东西(或空白屏幕),然后在功能结束时重建。

    您可以在创建小部件时将 Widget 变量设置为默认值,例如使用 CircularProgressIndicator,然后使用 setState 更改它,如下所示:

    class YourWidgetState extends State<YourWidget> {
      Widget _body = CircularProgressIndicator();  // Default Body
    
      @override
      void initState(){
        _gotoHomeScreen();
      }
    
      @override
      Widget build(BuildContext context){
        return _body;
      }
    
      Widget _gotoHomeScreen() {
        AuthService.getuserPrefEmail().then((email){
          AuthService.email = email;
          if (email == null) {
            setState(() => _body = LoginScreen());
          } else {
            AuthService.uid = email;
            setState(() => _body = HomeMenuScreen());
          }
        });
      }
    }
    

    另一种方法是使用变量通知您加载情况,例如bool finishedLoading,并在加载完成后调用setState 更改值,使用email 变量您设置知道用户何时登录,并进行有条件的构建,如下所示:

    bool loading = true;
    
    @override
    Widget build(BuildContext context){
      if(loading) return CircularProgressIndicator();
    
      if(AuthService.email == null)
        return LoginScreen();
      else
        return HomeMenuScreen();
    }
    
    Widget _gotoHomeScreen() {
      AuthService.getuserPrefEmail().then((email){
        AuthService.email = email;
        if (email != null) {
         AuthService.uid = email;
        }
        setState((){ loading = false; });
      });
    }
    

    【讨论】:

    • 谢谢@george 你救了我的一天
    【解决方案2】:

    使用简单的 FutureBuilder!

    https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

    FutureBuilder<Email>(
    future: AuthService.getuserPrefEmail(),
     builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
      switch (snapshot.connectionState) {
        case ConnectionState.active:
        case ConnectionState.waiting:
         return CircularProgressIndicator();
        case ConnectionState.done:
         if (snapshot.hasError) {
           return Text('Error: ${snapshot.error}');
          }
         .... here route to your screen or set it how you want
      }
     },
    )
    

    【讨论】:

    • 我觉得这个答案更好地概括了这个问题。
    猜你喜欢
    • 2021-03-24
    • 1970-01-01
    • 2019-02-10
    • 2022-12-14
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 2022-01-20
    • 2018-05-02
    相关资源
    最近更新 更多