前言

很多时候会依赖一些异步数据来动态更新UI,比如在打开一个页面时我们需要先从互联网上获取数据,在获取数据的过程中我们显示一个加载框,等获取到数据时我们再渲染页面;又比如想展示Stream(比如文件流、互联网数据接收流)的进度。当然,通过StatefulWidget完全可以实现上述这些功能。但由于在实际开发中依赖异步数据更新UI的这种场景非常常见,因此Flutter专门提供了FutureBuilder和StreamBuilder两个组件来快速实现这种功能。

接口描述

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

FutureBuilder({
// FutureBuilder依赖的Future,通常是一个异步耗时任务
this.future,
// 初始数据,用户设置默认数据
this.initialData,
// Widget构建器,该构建器会在Future执行的不同阶段被多次调用
// 构建器签名为:Function(BuildContext context, AsyncSnapshot snapshot)
// snapshot会包含当前异步任务的状态信息及结果信息,比如可以通过snapshot.connectionState获取异步任务的状态信息,通过snapshot.hasError判断任务时候有错误等
@required this.builder,
}) StreamBuilder({
Key key,
this.initialData,
Stream<T> stream,
@required this.builder,
})

代码示例

// 异步UI更新(FutureBuilder\StreamBuilder)

import 'dart:math';

import 'package:flutter/material.dart';

// 实现一个路由,当该路由打开时我们从网上获取数据,获取数据时弹一个加载框;获取结束时,如果成功则显示获取到的数据,如果失败则显示错误。
// 不真正去网络请求数据,而是模拟一下这个过程,隔3秒后返回一个字符串
Future<String> mockNetworkData() async{
return Future.delayed(Duration(seconds: 2), () => "我是从互联网上获取的数据!");
} class FutureBuilderTest extends StatelessWidget{
@override
Widget build(BuildContext context){
return 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();
}
},
),
);
}
} // 创建一个计时器的示例:每隔1秒,计数加1。这里,使用Stream来实现每隔一秒生成一个数字。
Stream<int> counter(){
return Stream.periodic(Duration(seconds: 1), (i){
return i;
});
} class StreamBuilderTest extends StatelessWidget{
@override
Widget build(BuildContext context){
return StreamBuilder<int>(
stream: counter(),
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:
// TODO: Handle this case.
return Text("active:${snapshot.data}");
case ConnectionState.done:
// TODO: Handle this case.
return Text("Stream已关闭");
}
return null;
},
);
}
}

总结

Dart中Stream 也是用于接收异步事件数据,和Future 不同的是,它可以接收多个异步操作的结果,它常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等。StreamBuilder正是用于配合Stream来展示流上事件(数据)变化的UI组件。在实战中,凡是UI会依赖多个异步数据而发生变化的场景都可以使用StreamBuilder。

最新文章

  1. 可变参数列表与printf()函数的实现
  2. html 之input标签height设置问题
  3. 教你如何快速下载旧版本的Firefox浏览器
  4. [logstash-input-file]插件使用详解
  5. iOS创建子工程
  6. 如何知道SQL语句的性能和改进途径
  7. POJ2486 Apple Tree(树形DP)
  8. C语言基础--while循环
  9. Most People Aren’t.
  10. C语言标准库函数strcpy与strcmp的简单实现
  11. 【HDOJ】Power Stations
  12. HTML5最佳实践
  13. Visual Studio中开发
  14. javascript 随机显示指定内容
  15. Chrome浏览器开发调试系列(一)
  16. [Oracle][DATAGUARD] 关于确认PHYSICAL STANDBY的同期状况的方法
  17. JAVA作业三
  18. flask 单个表单多个提交按钮
  19. input-event-codes.h
  20. Python 第一类对象

热门文章

  1. 题解 洛谷P6853 station
  2. ACM里的期望和概率问题 从入门到精通
  3. 算法(图论)——最小生成树及其题目应用(prim和Kruskal算法实现)
  4. STL——容器(Set &amp; multiset)的大小
  5. 使用uniapp开发项目来的几点心得体会,供新手参考参考
  6. el-amap 遮罩(带洞多边形)
  7. remmina 软件rdp协议链接windows失败
  8. Flutter AS设备连接显示loading解决方案
  9. 阿里云Centos7.6上面部署基于redis的分布式爬虫scrapy-redis将任务队列push进redis
  10. Python中的”黑魔法“与”骚操作“