Flutter:根据 Future 的快照采取行动

Bra*_*rad 5 dart flutter

我在尝试 Flutter 时遇到了一个我无法解决的问题。我正在考虑的案例有一个FutureBuilder如下所示的小部件:

 @override
    Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Example Page"),
        ),
        body: new FutureBuilder(
            future: _exampleFuture,
            builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.waiting: return new Center(child: new CircularProgressIndicator(),);
                default:
                  if(snapshot.hasError) {
                    return new Center(child: new Text('Error: ${snapshot.error}'),);
                  }
                  else {
                    return new Center(child: new Text("Result: ${snapshot.data}"),);
                  }
              }
            }
        )
    );
  }
Run Code Online (Sandbox Code Playgroud)

现在我们假设 future 是一个 http 调用,最终会出现 401 错误,表明用户未经授权。此时,我希望应用程序删除存储的任何令牌并重定向到登录页面或只是重建应用程序。但我无法调用在构建函数中执行此操作的方法,并且我认为不能didUpdateWidget()保证被调用,因为未来可能会在build调用之前返回它的值?也许我的做法完全错误,但是有没有办法在 Flutter 中做到这一点?

azi*_*iza 4

您可以检查statusCode您的Async方法内部,并setState根据该值来删除令牌的值statusCode;否则,如果连接被授权,则返回您想要的数据。现在,在您的 中FutureBuilder,检查您的快照是否为空以显示页面SignIn()

例如,处理 http 请求的方法可能类似于:

_Request() async {
    var httpClinet = createHttpClient();
    var response = await httpClinet.get(
        url, headers: {'Authorization': "Bearer $_currentUserToken"});
    if (response.statusCode == 200) {
      var myRequest = JSON.decode(response.body);
      var myDesiredData;

      ///TODO: Some data conversions and data extraction
      return myDesiredData;
    }
    else {
      setState(() {
        _currentUserToken = null;
      });
      return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以拥有像这样的 FutureBuilder:

@override
Widget build(BuildContext context) {
  return new FutureBuilder(
      future: _request(),
      builder: (BuildContext context, AsyncSnapshot response) {
        response.hasData==false? new SignIn(): new Scaffold(
          appBar: new AppBar(title: new Text("Future Builder"),),
          body: new Center(
            child: new Text("Build your widgets"),
          ),
        );
      },
   );
}
Run Code Online (Sandbox Code Playgroud)