为什么 futureBuilder 回调在 facebook 以 flutter 登录数据后不调用?

why futureBuilder callback is not calling after facebook logged in data in flutter?

我是 flutter 的新手,所以如果我是 wrong.In 我的应用程序,请告诉我我必须使用 facebook 登录,所以我使用了 RawMaterialButtononPressed 函数使用以下代码

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 条件状态 checking.I 找不到原因。我也检查以下堆栈问题。

好吧,在您的 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 在登录页面的小部件之间创建一种通信方式,因为你想通过按下按钮来更改 page/view 小部件的状态,你可以使用一个 StatefulWidget 但你应该看到 this tutorial better. and here 是提供者文档。

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

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

使用 navigator.push(),您可以更改屏幕上的 view/page/widget 并显示一个新的小部件,该小部件可以显示与响应值相关的内容。