Code前端首页关于Code前端联系我们

Flutter FutureBuilder 优雅地构建了异步用户界面

terry 2年前 (2023-09-23) 阅读数 73 #移动小程序

在实际开发中,一般需要在显示列表内容之前显示loading。这意味着它正在加载。上传成功后,会显示列表内容。如果加载失败,会显示失败的界面

所以,这样的请求会涉及三种情况:

  • 正在加载
  • 加载成功显示列表
  • 加载失败,显示错误

我们知道Flutter UI是一个声明式UI

当你在不同的UI之间切换时,它是通过setState重建的。因此,对于上面三个用户界面的例子,我们需要使用if else来判断显示哪个界面。。需要维护很多变量,非常不优雅。管理

  • builder 根据异步任务状态构建不同的 Widget 与上面类似 if/else
  • FutureBuilder ,异步任务状态为:

    状态 描述
    n未连接到任何异步任务
    waiti ng已连接到等待交互的异步任务
    活动 连接到激活的异步任务
    done与已完成的异步任务相关联

    为了改造上面的例子,我们可以使用FutureBuilder,代码如下:

    FutureBuilder<int>(
        future: _loadList(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.none:
            case ConnectionState.waiting:
            case ConnectionState.active:
              // 显示正在加载
              return createLoadingWidget();
            case ConnectionState.done:
              // 提示错误信息
              if (snapshot.hasError) {
                return createErrorWidget(snapshot.error.toString());
              }
              // 展示列表内容
              return ListView.separated(
                itemCount: snapshot.data,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(title: Text(index.toString()));
                },
                separatorBuilder: (BuildContext context, int index) {
                  return divider;
                },
              );
            default:
              return Text("unknown state");
    )
    复制代码

    需要注意的是,上面的代码接口每个time 重建时会执行loadList操作。

    不过,有时候界面改变时,不需要重做未来。比如界面是Tab + ListView(文章类别+文章列表),必须先加载文章分类,然后文章分类的异步任务是future。分类加载成功后,即可加载项目列表。当列表加载成功后,界面将被重建。这次,文章类别(未来)

    无法重新加载。目前需要将变量future作为成员变量,在initState中初始化,然后传递给future参数,如:

    Future _future;
    
    @override
    void initState() {
        _future = _loadList();
        super.initState();
    }
    
    FutureBuilder<int>(
        future: _future,
        ...
    )
    复制代码

    执行效果如下图: Flutter FutureBuilder 优雅构建异步UI

    FutureBuilder源码分析

    FutureBuilder继承了StatefulWidget,所以主要代码集中在State

    除了StreamBuilder

    中的FutureBuilder可以优雅地构建异步UI之外,还可以实现StreamBuilder,但一般来说,作为一个UI的展示同步任务,它不是一个 Stream Stream 的形式,更像是一次性的逻辑处理。只要成功,一般不需要更新,所以使用FutureBuilder就完全足够了。实际开发中,根据情况进行选择。 StreamBuilder 功能更强大。如果以后向stream发送数据,用户界面也会相应改变。例如:

    StreamBuilder<int>(
      // 这个是stream 而不是 future
      stream: _streamController.stream,
      initialData: _counter,
      builder: (BuildContext context, AsyncSnapshot<int> snapshot){
        // 接收到 controller 发送给 stream 的数据
        return Text('${snapshot.data}');
      }
    ),
    )
    复制代码

    我们可以通过_streamController发送数据,那么就会被自动调用。 StreamBuilder 构建器

    刷新Widget

    _streamController.sink.add(++_counter);
    复制代码

    的回调。当然,也可以提供 stream 而不传递 StreamController ,或者您也可以创建一个返回 的函数流动。

    作者:Chiclaim
    来源:掘金

    版权声明

    本文仅代表作者观点,不代表Code前端网立场。
    本文系作者Code前端网发表,如需转载,请注明页面地址。

    发表评论:

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    热门