首页 > 编程语言 >直播系统源码,异步加载UI相关知识点

直播系统源码,异步加载UI相关知识点

时间:2024-08-17 10:38:05浏览次数:9  
标签:知识点 return 异步 接口 FutureBuilder state 源码 UI Future

简述

FutureBuilder和StreamBuilder都是Flutter为开发者提供快速实现异步加载UI的方案,它们不同的是一个依赖的是Future另一个依赖的是Stream,一般情况下我们使用Future就可以完成大部分的异步操作,它可以异步加载我们需要的数据,那Stream是不是多余的呢?并不是,Stream专门用于异步加载流的类型,比如文件的读写和网络文件的下载等等场景,所以它们各有各的特长,小伙伴们在看完这篇文章之后可以根据实际的业务需求在它们之间选择。
接下来先看看FutureBuilder的具体使用。

FutureBuilder异步

const FutureBuilder({
  super.key,
  required this.future,
  this.initialData,
  required this.builder,
});

 

FutureBuilder的构造函数非常简单,只有四个参数:

future参数用于接收一个Future类型的对象,用于处理异步请求;
initialData参数可以定义初始值,在异步操作未完成之前可以使用此参数的值来展示页面信息;
builder参数则是处理异步回调操作的逻辑,可以在此参数内部处理异步操作完成前后的逻辑并返回指定的Widget。

class _FutureState extends State<FutureWidgetExample> {
  @override
  Widget build(BuildContext context) {
    return buildScaffold(
      context,
      Center(
        child: FutureBuilder(
          future: buildFuture(),
          builder: (context, result) {
            var state = result.connectionState;
            debugPrint('future state: ${state.name}');
            if (state == ConnectionState.done) {
              return Text(result.data ?? "Future Error");
            } else {
              return const CircularProgressIndicator();
            }
          },
        ),
      ),
    );
  }

  Future<String> buildFuture() async {
    return Future.value('Future value');
  }
}

log:
future state: waiting
future state: done

 

这里我们通过FutureBuilder创建了一个异步加载的UI,future参数传入的是buildFuture()方法,此方法内部采用了最简单的Future.value()返回了一个字符串;然后builder参数内部根据ConnectionState类型返回了两种不同的Widget,如果state为done那么就返回一个Text来展示Future的结果,如果state非done那么就展示加载loading。
因为buildFuture()方法内部是直接返回的结果,此代码会看不到加载loading,我们可以将Future.value()改为

Future<String> buildFuture() async {
    return Future.delayed(const Duration(seconds: 2), () {
      return 'Future value';
    });
  }

 

这样我们先延时2s之后再返回字符串,这样就可以很清晰的看出界面的变化

这里我们再了解下ConnectionState概念,它一个有四种状态,分别为:

none:此状态表示FutureBuilder中future参数传入的为空,当前没有异步任务在执行;
waiting:此状态表示异步任务正在执行,还没收到最终结果;
active:此状态在FutureBuilder中不容易理解,在后面的StreamBuilder中可以很容易的理解,它表示的是当前异步任务已经收到了返回的数据,但是异步任务并没有结束,后面还会收到别的数据;可以用读取文件的任务来加深理解,读取文件是一个过程,从开始到结束会一直接受文件的流,在未接收完之前ConnectionState会一直是active状态,等到整个文件都接收完成之后,active状态就会变为done状态;
done:此状态表示的是异步任务已经完成。

上面就是ConnectionState四种状态的概括性解释,上述代码中我们也是添加了debugPrint来输出state,大家可以执行下代码来看看整个任务的state是如何变化的,此时state的变化是:waiting -> done,因为我们buildFuture是一个一次性的任务,所以中途不会出现active状态,active状态我们会在StreamBuilder种介绍。

StreamBuilder异步

const StreamBuilder({
  super.key,
  this.initialData,
  required super.stream,
  required this.builder,
});

 

对比FutureBuilder的构造函数来看,StreamBuilder和它的区别就在于stream参数,其余的基本上是一致的,这里就不过多解析了,直接进入实战环节。

class _StreamState extends State<StreamWidgetExample> {
  @override
  Widget build(BuildContext context) {
    return buildScaffold(
      context,
      Center(
        child: StreamBuilder(
          initialData: "init stream data",
          stream: buildStream(),
          builder: (context, result) {
            var connectionState = result.connectionState;
            debugPrint('stream state: ${connectionState.name}');
            if (connectionState == ConnectionState.done) {
              return Text(result.data ?? 'Stream error');
            } else {
              return Text(result.data ?? 'init data');
            }
          },
        ),
      ),
    );
  }

  Stream<String> buildStream() {
    return Stream.periodic(const Duration(seconds: 1), (i) {
      return "$i";
    });
  }
}

 

使用方式也是类似于FutureBuilder,不过这里我们多传入了一个initialData参数,然后在buildStream()方法里使用的是Stream.periodic()方法返回的Stream对象,periodic表示的是周期性任务,这里定义的每隔1s返回阶段性的结果。使用periodic()方法的目的是为了可以清晰的展示initialData的作用。
通过debugPrint的日志可以看出,ConnectionState的状态在第一次周期任务结束之前一直是waiting状态,后面都是active状态,并且这里不会有done状态,因为我们Stream.periodic是一直在跑的,实际开发中读取文件或者下载文件等操作还是会有done状态的。
这里注意的是在builder参数内部我们非done状态是展示的是Text,Text的内容为result.data,试想一下周期任务的前1s还未收到阶段性结果,此时会Text的内容会展示啥呢?下面来看下具体运行的效果图。

通过上面的GIF可以看出,在前1s的时候Text展示的是initialData值,然后每隔1s显示的内容从0依次+1。
通过上面的介绍,FutureBuilder和StreamBuilder相关知识就梳理完成了,异步加载UI的内容在日常开发中还是使用的蛮多的,小伙伴们如果是第一次接触可能会感觉到有点繁琐,但是用多了就会逐渐熟练起来,最后我们通过FutureBuilder的方式加载接口数据再次熟悉一下,这种方式也是实际开发接触的比较多的~

Dio加载接口数据

dio 是一个强大的 HTTP 网络请求库,支持全局配置、Restful API、FormData、拦截器、 请求取消、Cookie 管理、文件上传/下载、超时、自定义适配器、转换器等。

以上是Dio官方的介绍,详细使用可以去阅读Dio的官方文档
引入Dio库
在使用Dio之前,我们先在工程的pubspec.yaml文件中引入Dio库

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  dio: 

 

然后再Android模块的Manifest文件中添加网络权限,不然接口请求就不会成功的哈~

定义接口数据类
接口请求我们使用的是WanAndroid开放的Api,日常调试接口的神级接口,

以首页数据接口为例,现在浏览器中请求一次,拿到接口的返回数据,然后在Json To Dart网页中生成实体类。这里生成的实体类代码有点多,就不在文章中贴出具体代码了。

接口请求

Future<Response> fetchArticle() {
  Dio dio = Dio();
  return dio.get("https://www.wanandroid.com/article/list/0/json");
}

 

采用Dio方式实现接口请求非常简单,只需要通过Dio.get()就可以完成一个Get类型的接口请求,它返回的是Future类型的对象,看到Future类型小伙伴是不是就知道如何展示接口数据了,只需要通过FutureBuilder的形式就可以完成接口数据的展示,下面直接贴代码。

接口数据展示

class _DioState extends State<DioWidget> {
  @override
  Widget build(BuildContext context) {
    return buildScaffold(
      context,
      Center(
        child: FutureBuilder(
            future: fetchArticle(),
            builder: (context, result) {
              ConnectionState state = result.connectionState;
              if (state == ConnectionState.done) {
                Article article = Article.fromJson(result.data?.data);
                return ListView.builder(
                    itemCount: article.data?.size ?? 0,
                    itemBuilder: (context, index) {
                      return ListTile(
                        title: Text("${article.data!.datas?[index].title}"),
                      );
                    });
              } else {
                return const CircularProgressIndicator();
              }
            }),
      ),
    );
  }
}

 

上述代码中在第8行出将接口请求的Future传入给FutureBuilder,然后在第12行处进行数据的Json解析,Article.fromJson()方法就是通过Json To Dart生成出来的,不需要小伙伴自己手动编写,这样我们就拿到了最终想要的数据类型,通过Article对象绘制了一个列表界面,每个Item只显示文章的标题。

到此为止我们就通过Dio+FutureBuilder的方式实现了一个接口请求,并且将请求后的数据展示到界面上,整体来说还是比较简单的,哈哈~得益于Flutter的响应式布局。

标签:知识点,return,异步,接口,FutureBuilder,state,源码,UI,Future
From: https://www.cnblogs.com/yunbaomengnan/p/18364114

相关文章

  • h5直播源码,用户登录流程及权限校验
    h5直播源码,用户登录流程及权限校验今天我们来看一下用户登录的流程前端部分 以一个后台管理系统登录为例:登录篇1.用户输入账号和密码点击登录传给服务器用户名和密码2.服务器验证成功后给客户端传递一个token,并且把这个token存在cookies中,这样下次再向服务器发请......
  • 设计模式---构建者模式(Builder Pattern)
    构建者模式(BuilderPattern)是一种创建型设计模式,旨在将复杂对象的构建过程与其表示分离。它允许使用相同的构建过程创建不同的表示。该模式通常用于构建复杂对象,这些对象由多个部分组成或具有多个可选属性。构建者模式的核心要素:Builder(构建者):定义构建对象的接口,声明创建部......
  • 基于SpringBoot+Vue+uniapp的图书商城网站的设计和开发(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 基于SpringBoot+Vue+uniapp的快递管理系统(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 基于SpringBoot+Vue+uniapp的咖啡销售系统(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 1、.Net UI框架:MAUI - .Net宣传系列文章
    .NETMAUI(Multi-platformAppUI)是一个跨平台的UI框架,它是.NET统一应用模型的一部分,允许开发者使用C#和.NET来创建适用于iOS、Android、macOS和Windows的应用程序。MAUI继承了Xamarin.Forms的一些概念,但提供了更多的原生平台集成和改进的性能。MAUI的关键特性包括:......
  • 黑马毕设分享《基于SSM框架学生考勤管理系统的设计与实现》(源码+lw+部署文档+讲解等)
    文章目录1.前言黑马设计——专注大学生的项目实战开发,免费讲解,毕业答疑辅导黑马设计工作室简介:黑马设计是一家专注大学生的项目实战开发,免费讲解,毕业答疑辅导的工作室✅,创始人是硕士毕业于华南理工大学,工科专业,目前团队成员全职+兼职上百余人,运营线上店铺2家,与B站(IT实......
  • 黑马毕设分享《基于Java的失物招领管理系统的设计与实现》(源码+lw+部署文档+讲解等)
     文章目录1.前言黑马设计——专注大学生的项目实战开发,免费讲解,毕业答疑辅导黑马设计工作室简介:黑马设计是一家专注大学生的项目实战开发,免费讲解,毕业答疑辅导的工作室✅,创始人是硕士毕业于华南理工大学,工科专业,目前团队成员全职+兼职上百余人,运营线上店铺2家,与B站(IT实......
  • 【本地+在线】Comfyui的基本工作流的搭建----文生图+图生图
    一.(本地使用comfyui)基本模块的了解1.1这是初始界面1.2搭建一个基本的工作流(如果使用的是秋叶大佬的包,每次进入会自动出现该工作流)1.2.1加载器和取样器:加载器,鼠标右键,点击新建节点,按下图操作,出现加载器取样器,鼠标右键,然后按下图操作可以看到如图结果:我们将“模型“连接......
  • java guide Spring Cloud Gateway 答疑5
    LoadBalancerClientFilter怎么用`LoadBalancerClientFilter`是SpringCloudGateway中的一个内置过滤器,用于将请求路由到负载均衡的后端服务。它利用SpringCloudLoadBalancer或NetflixRibbon(如果在使用)来实现负载均衡。###配置示例要使用`LoadBalancerClientFilt......