【Flutter】功能型组件之异步UI更新
前言
很多时候会依赖一些异步数据来动态更新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。
【Flutter】功能型组件之异步UI更新的更多相关文章
- 执行异步UI更新
异步更新UI的几种方法①.使用Control.Invoke方式来更新数据 foreach (DataGridViewRow dgvr in this.dgv_s ...
- C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较
使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新 使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和 ...
- Flutter走过的坑(持续更新)
1 Target of URI doesn't exist 'package:flutter/material.dart' 官方下载的flutter中有一个example文件夹,里面有很多flutte ...
- Flutter InkWell - Flutter每周一组件
Flutter Inkwell使用详解 该文章属于[Flutter每周一组件]系列,其它组件可以查看该系列下的文章,该系列会不间断更新:所有组件的demo已经上传值Github: https://gi ...
- Flutter ListTile - Flutter每周一组件
该文章属于[Flutter每周一组件]系列,其它组件可以查看该系列下的文章,该系列会不间断更新:所有组件的demo已经上传值Github: https://github.com/xj124456/fl ...
- 免费素材:包含 250+ 组件的 DO UI Kit
DO UI kit 现在可以免费用于 Photoshop 和 Sketch 了.它有超过130个屏幕,10个完整的主题以及250+的组件混合以创造惊人的应用.他们都是再混合和视网膜.最重要的是他们看起 ...
- android开发之在activity中控制另一个activity的UI更新
转自:http://blog.csdn.net/jason0539/article/details/18075293 第一种方法: 遇到一个问题,需要在一个activity中控制另一个acitivit ...
- 【Cocos2d-Js基础教学(7)界面UI更新方法(会用到第三方类库)】
我们游戏中会遇到很多UI更新的时候,大部分时候我们会remove该节点,再重新绘制的方法来进行UI更新. 但是这种更新效率并不高,这里我推荐大家一个第三方的库,来通过注册更新的方式来对UI进行更新管理 ...
- WPF多线程UI更新——两种方法
WPF多线程UI更新——两种方法 前言 在WPF中,在使用多线程在后台进行计算限制的异步操作的时候,如果在后台线程中对UI进行了修改,则会出现一个错误:(调用线程无法访问此对象,因为另一个线程拥有该对 ...
随机推荐
- 题解-[NOI2005]瑰丽华尔兹
题解-[NOI2005]瑰丽华尔兹 [NOI2005]瑰丽华尔兹 \(n\times m\) 的矩阵.以 \((x,y)\) 为起点.一共 \(k\) 段时间,每段时间为 \([s_i,t_i](t_ ...
- Kubernetes Python Client 初体验之安装授权
最近想做一个基于flask的云平台管理服务器,利用python调用kubenetes提供的API来实现云平台的操作.笔者使用的是Windows,kubernetes集群安装在Ubuntu和Respbi ...
- PhotoSwipe用法
1.自动识别data-size问题,添加以下代码 gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options) ...
- [打基础]OI/ACM基本功&一些小功能的实现&一些错误(持续更新)
基本功 前导0 如题,有时候需要把3输出成03这样子,可以调用 cout.width(x); ,x表示以几位,用 cout.fill(x); 来给出前导填充的内容,一般x以char的形式给出 例如可以 ...
- [打基础]一些C++自带的库(持续更新)
iomanip manip是manipulator(嗯,操作器?)的缩写,对应头文件就是 #include<iomanip> 在算法竞赛里用得到的应该是两个接口:进制转换(8,10,16) ...
- [日常摸鱼]bzoj1502[NOI2005]月下柠檬树-简单几何+Simpson法
关于自适应Simpson法的介绍可以去看我的另一篇blog http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题意:空间里圆心在同一直线上且底面 ...
- 什么是java的深浅拷贝?
什么是java的深浅拷贝? 浅拷贝 就是很肤浅的拷贝,只拷贝了别人的地址.没有拷贝地址里面的值.地址里面的值改变后,就都改变了. 深拷贝 就是很深入的拷贝,深入到核心的拷贝,拷贝了别人地址里面的值,别 ...
- 数字crawlergo动态爬虫结合长亭XRAY被动扫描
群里师傅分享了个挖洞的视频,搜了一下,大概就是基于这篇文章录的 https://xz.aliyun.com/t/7047 (小声哔哔一下,不得不说,阿里云先知社区和360酒仙桥六号部队公众号这两个地方 ...
- angular8 页面滚动到某一个特定位置
背景:使用angular8安装的 Fuse-v8.0.0-demo 后台的框架 锚点: id='nearby' 流程:无论是点击触发方法也好,还是直接调用方法也好,这里只写 引入: import {C ...
- 4.自定义view-进度条控件
1.效果 2.实现原理 画圆,画圆弧,画文字 外部控制进度,通过invalidate()方法更新 核心代码: @Override protected void onDraw(Canvas canvas ...