Flutter:在构建之前等待一个函数

标签 flutter asynchronous async-await sharedpreferences

我在我的应用程序中为用户创建了一个个人资料页面,可以使用他们自己的帐号和密码登录和注销。我使用 SharedPreference 将数据存储在本地设备中,包括 bool 'logined',在用户登录后将设置为 'true'(默认为 'false')。问题来了。我想在用户每次导航到此页面时向用户展示他们自己的个人资料页面,而无需在登录后再次登录页面。因此,在构建此页面之前,我必须检查“登录”变量是否为“真”或“假”。如果为真,则导航到个人资料页面。如果为 false,则显示登录页面。但是,实际上,登录页面总是在 LoginedCheck 函数(用于检查“已登录”变量和导航)完成其工作之前显示。将显示登录页面,然后快速转到个人资料页面。我尝试使用“延迟”来等待 LoginedCheck(),但在创建个人资料页面之前屏幕会变黑。有解决问题的想法吗?例如,谢谢。

构建方法:

Widget build(BuildContext context) {
    LoginedCheck();
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      body: Stack(
        children: <Widget>[
          Container(
            height: double.infinity,
            width: double.infinity,
            decoration: BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter,
                  colors: [
                    Color(0xFF73AEF5),
                    Color(0xFF61A4F1),
                    Color(0xFF478DE0),
                    Color(0xFF398AE5),
                  ],
                  stops: [0.1,0.4,0.7,0.9],
                )),
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  SizedBox(
                    height: 10,
                  ),
                  Icon(
                    Icons.account_circle,
                    size: 150.0,
                  ),
                  SizedBox(height: 30),
                  Container(
                    width: 300,
                    child: Theme(
                        data: ThemeData(
                          primaryColor: Colors.white,
                          primaryColorDark: Colors.yellowAccent,
                        ),
                        child: TextField(
                          controller: _LtextFieldAccount,
                          decoration: InputDecoration(
                              border: OutlineInputBorder(),
                              hintText: '請輸入帳號',
                              prefixIcon: const Icon(Icons.person)),
                        )),
                  ),
                  SizedBox(height: 20),
                  Container(
                    width: 300,
                    child: Theme(
                        data: ThemeData(
                          primaryColor: Colors.white,
                          primaryColorDark: Colors.yellowAccent,
                        ),
                        child: TextField(
                          controller: _LtextFieldID,
                          decoration: InputDecoration(
                              border: OutlineInputBorder(),
                              hintText: '請輸入密碼',
                              prefixIcon: const Icon(Icons.lock)),
                        )),
                  ),
                  SizedBox(height: 30),
                  RaisedButton(
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(25.0)),
                    elevation: 4.0,
                    color: Colors.white,
                    child: Container(
                      padding: EdgeInsets.only(
                          left: 10,right: 10,top: 10,bottom: 10),
                      child: Text(
                        '登入',
                        style:
                        TextStyle(fontSize: 25,color: Colors.blueAccent),
                      ),
                    ),
                    onPressed: Login,
                  ),
                  SizedBox(height: 20),
                  RaisedButton(
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(25.0)),
                      elevation: 4.0,
                      color: Colors.white,
                      child: Container(
                        padding: EdgeInsets.only(
                            left: 10,right: 10,top: 10,bottom: 10),
                        child: Text(
                          '新用戶註冊',
                          style:
                          TextStyle(fontSize: 25,color: Colors.blueAccent),
                        ),
                      ),
                      onPressed: (){
                        Navigator.of(context).push(MaterialPageRoute(
                            builder: (context) => RegisterPage()));
                      })
                ],
              ),
            ),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        onTap: onTabTapped,
        currentIndex: _currentIndex, //thiswillbesetwhenanewtabistapped
        items: [
          new BottomNavigationBarItem(
            icon: new Icon(Icons.school),
            title: new Text('大學'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.directions_subway),
            title: new Text('交通'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.person),
            title: new Text('個人'),
          )
        ],
      ),
    );
  }

LoginedCheck() 函数:

Future LoginedCheck() async{
    SharedPreferences prefs = await SharedPreferences.getInstance();

    bool logined = prefs.getBool(_StorageLogined) ?? false;
    int GetUserNum = prefs.getInt(_StorageUserNum) ?? 0;

    if(logined == true) {
      Navigator.of(context).push(MaterialPageRoute(
          builder: (context) => ShowProfile(UserNum: GetUserNum,)));
    }
  }

最佳答案

您的标题与您的问题不符。事实上,您基本上提供了 3 个问题:

如何在 build 之前/之中等待函数?: 你不需要,build 可以被多次调用,它并不真正在你的控制之下,何时或如何被调用,你不应该对它做出假设。相反,您可以使用 FutureBuilder 构建 2 个不同的小部件,具体取决于 Future 是否解析。

如何在页面入口处自动导航?: 在 initState 中触发检查和导航方法,但您无法阻止第一个页面的构建/显示(因为您首先在该页面上导航)。

如何进行条件导航?: 您首先等待 future ,然后导航。

对于您的用例: 你想做条件导航,所以在你导航到你的登录页面(大概是你应用程序的第一页)之前,提供类似启动页面的东西,你可以在其中检查用户是否登录。在未来解决之后,你做导航到配置文件或登录屏幕。您可以将其包装在一个函数中,以便在其他页面上重复使用此条件导航,您可以在其中登陆登录页面或个人资料页面。

关于Flutter:在构建之前等待一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62829298/

相关文章:

dart - Flutter:带有 CircleAvatar 的卡片,突出显示

c# - 获取异步等待和任务工作

javascript - 如何在异步函数中抛出异常?

c# - 具有受控并行性和 AwaitAll 选项的异步任务

Flutter - 异步文件读取异常处理

Flutter 无法从另一个类调用异步函数

flutter - 获取在 Flutter CustomScrollView 中可见/滚动的当前条子

tabs - 我可以将 TabBar 和 TabBarView 用作页面小部件吗?

c# - 多客户端服务器-客户端断开连接和异步错误后,接收事件变得疯狂

javascript - 如何用Dojo组织异步代码?