Flutter 异步UI及stream

很多时候,我们都需要一些异步的数据来更新界面显示UI,如:启动一个App时先加载loading页面,待请求用户数据返回后再更新;下拉加载更多内容时,显示加载动画gif,数据返回时渲染页面显示。Flutter专门提供了FutureBuilderStreamBuilder两个组件来快速实现异步数据更新UI的功能。

FutureBuilder

FutureBuilder会依赖一个Future,它会根据所依赖的Future的状态来动态构建自身。

const FutureBuilder({
    Key key,
    this.future,
    this.initialData,
    @required this.builder,
  }) : assert(builder != null),
       super(key: key);
  • future FutureBuilder依赖的future,通常是一个异步耗时任务
  • initData 用户设置的默认数据
  • builder widget构造器,在future状态发生变化时被调用
builder: (BuildContext context, AsyncSnapshot<Map> snapshot)

snapshot会包含当前异步任务的状态信息及结果信息,通过snapshot.connectionState获取异步任务的状态信息、通过snapshot.hasError判断异步任务是否有错误等等

Creates an [AsyncSnapshot] with the specified [connectionState],
and optionally either [data] or [error] (but not both).

实现一个路由,当该路由打开时我们从网上获取数据,获取数据时弹一个加载框;获取结束时,如果成功则显示获取到的数据,如果失败则显示错误。

FutureBd

class FutureBd extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // 路由界面返回 Scaffold为路由的骨架页
  return new Scaffold(
    appBar: new AppBar(
        title: new Text("Future Build"),
      ),
    body: new Center(
      child: FutureBuilder<String>(
      future: mockNetworkData(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        // 请求已结束
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            // 请求失败,显示错误
            return Text("Error: ${snapshot.error}");
          } else {
            // 请求成功,显示数据
            return Text("Contents: ${snapshot.data}");
          }
        } else {
          // 请求未结束,显示loading
          return CircularProgressIndicator();
        }
      },
    ),
    ),
  );
}
}

Future<String> mockNetworkData() async {
  return Future.delayed(Duration(seconds: 2), () => "我是从互联网上获取的数据");
}

ConnectionState类定义

enum ConnectionState {
  /// 当前没有异步任务,比如[FutureBuilder]的[future]为null时
  none,

  /// 异步任务处于等待状态
  waiting,

  /// Stream上已经有数据传递,对于FutureBuilder没有该状态。
  active,

  /// 异步任务已经终止.
  done,
}

StreamBuilder

StreamBuilder是用于配合Stream(可以发送接收多个异步事件)来展示流上事件(数据)变化的UI组件。

StreamBuilder({
  Key key,
  this.initialData,
  Stream<T> stream,//区别于FutureBuilder 接收一个stream
  @required this.builder,
})

创建一个计时器的示例:每隔1秒,计数加1

Stream<int> counter() {
  return Stream.periodic(Duration(seconds: 1), (i) {
    return i;
  });
}

class BuildBdInside extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
       new Center(
      child: StreamBuilder<int>(
        stream: counter(), //
        //initialData: ,// a Stream or null
        builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
          if (snapshot.hasError) return Text('Error: ${snapshot.error}');
          switch (snapshot.connectionState) {
            case ConnectionState.none:
              return Text('没有Stream');
            case ConnectionState.waiting:
              return Text('等待数据...');
            case ConnectionState.active:
              return Text('active: ${snapshot.data}');
            case ConnectionState.done:
              return Text('Stream已关闭');
          }
          return null; // unreachable
        },
      ),
    )
    ],);
  }
}

FutureBuilder: 一般的异步任务,像是一次性的逻辑处理, 只要成功后, 一般不需要更新
StreamBulider:功能更加强大,后期如果往 stream 中发送数据,则对应的 UI 界面也跟着发生变化

你可能感兴趣的:(flutter,计算机)