0

我是颤振的新手,所以如果我错了,请告诉我。在我的应用程序中,我必须使用 facebook 登录,所以我在使用下面的代码中使用了一个RawMaterialButton和函数onPressed

child: RawMaterialButton(
                    onPressed: () {
                      FutureBuilder<String>(
                        future:
                            _login(), // function where you call your api
                        builder: (BuildContext context,
                            AsyncSnapshot<String> snapshot) {
                          // AsyncSnapshot<Your object type>
                          print(snapshot);
                          if (snapshot.connectionState ==
                              ConnectionState.done) {
                            print('${snapshot.data}');
                          }
                          if (snapshot.connectionState ==
                              ConnectionState.waiting) {
                            return Center(
                                child: Text('Please wait its loading...'));
                          } else {
                            if (snapshot.hasError)
                              return Center(
                                  child: Text('Error: ${snapshot.error}'));
                            else
                              return Center(
                                  child: new Text(
                                      '${snapshot.data}')); // snapshot.data  :- get your object which is pass from your downloadData() function
                          }
                        },
                      );
                      return CircularProgressIndicator();
                    },

当我按下按钮调用该方法并且我正在获取数据但在获取这些数据之后,未来的构建不会更新或显示该数据。Text这里是我的数据获取方法。

  Future<String> _login() async {
final result = await FacebookAuth.instance.login();
var tokenString;
switch (result.status) {
  case FacebookAuthLoginResponse.ok:
    _printCredentials(result);
    // get the user data
    // final userData = await FacebookAuth.instance.getUserData();
    tokenString = result.accessToken.token;
    break;
  case FacebookAuthLoginResponse.cancelled:
    print("login cancelled");
    tokenString = "User cancelled";
    break;
  default:
    tokenString = "Login failed";
}
return tokenString;
}

出于调试目的,我也设置了断点,但它没有针对asynchronous snapshot条件状态检查。我找不到原因。我还检查了以下堆栈问题。

为什么 FutureBuilder 在 Flutter 中没有被调用? Flutter FutureBuilder 未更新

4

1 回答 1

1

好吧,在您的 onPressed 函数中,您声明了一个 FutureBuilder ,这绝对是错误的。FutureBuilder 允许您对函数或方法发出异步请求,以根据快照值使用响应数据构建小部件或其他小部件。当您第一次运行小部件或在 StatefulWidget 中使用 SetState({}) 时会发生这种情况。但是您正在将视图代码与功能代码结合起来。这是实现 FutureBuilder 的方法:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _login(),
      builder: (context, snapshot) {
        print(snapshot);
        if (snapshot.connectionState == ConnectionState.done) {
          print('${snapshot.data}');
        }
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(child: Text('Please wait its loading...'));
          // Or return CircularProgressIndicator();
        } else {
          if (snapshot.hasError)
            return Center(child: Text('Error: ${snapshot.error}'));
          else
            return Center(
                child: new Text(
                    '${snapshot.data}'));
        }
      },
    );
    // if you return something here, it's dead code
  }

但我建议你以这种方式实现 FutureBuilder:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      child: FutureBuilder(
        future: _login(),
        builder: (context, snapshot) {
          if (snapshot.hasError) // if it has error
            return Text('Error: ${snapshot.error}');
          if (!snapshot.hasData) {
            // if it's loading
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('Please wait its loading...'),
                Padding(
                  padding: EdgeInsets.only(top: 20),
                  child: Container(
                    height: 35,
                    width: 35,
                    child: CircularProgressIndicator(),
                  ),
                ),
              ],
            );
          } else {
            // if everything success
            print(snapshot.data);
            return Text('${snapshot.data}');
          }
        },
      ),
    );
  }

最后,我认为您想要的是使用 Provider 在登录页面中的小部件之间创建一种通信方式,因为您想通过按下按钮来更改页面/视图小部件的状态,您可以使用 StatefulWidget 但您应该看到这个教程更好。是提供者文档。

Pdst:但是,如果您不想实现提供程序,您可以在按钮中发出 _login() 请求,例如:

onPressed: () async {
  String response = await _login();
  Navigator.push(context, MaterialPageRoute(builder: (context) => ResponseWidget(response)));
}

navigator.push()您可以更改屏幕中的视图/页面/小部件,并显示一个新的小部件,该小部件可以显示取决于响应值的内容。

于 2020-10-26T18:01:13.060 回答