flutter开发实战-StreamBuilder使用介绍及实例

flutter开发实战-StreamBuilder使用介绍及实例

StreamBuilder是一个Widget,它依赖Stream来做异步数据获取刷新widget。

一、Stream

Stream是一种用于异步处理数据流的机制,它允许我们从一段发射一个事件,从另外一段去监听事件的变化.Stream类似于JavaScript中的Promise、Swift中的Future或Java中的RxJava,它们都是用来处理异步事件和数据的。Stream是一个抽象接口,我们可以通过StreamController接口可以方便使用Stream。

  • StreamController 流控制器

通过StreamController,我们可以监听暂停、恢复、取消、完成、错误等事件

 final streamController = StreamController(onPause: () => print('Paused'),onResume: () => print('Resumed'),onCancel: () => print('Cancelled'),onListen: () => print('Listens'),);streamController.stream.listen((event) => print('Event: $event'),onDone: () => print('Done'),onError: (error) => print(error),);
  • StreamSink 用作发射事件

StreamSink可以通过streamController获取,streamController.sink。
StreamSink发射事件调用add方法

  • Stream 用作事件的监听

Stream 可以通过streamController获取,streamController.stream
Stream 监听则可以调用listen方法

  • StreamSubscription 用作管理监听,关闭、暂停等

streamSubscription 通过Stream调用listen获取。streamSubscription有暂停、恢复、关闭、取消等方法。

二、Stream的使用

Stream使用的步骤如下

  /// 获取StreamSubscription用作管理监听,关闭暂停等StreamSubscription<int>? subscription;/// StreamControllerStreamController<int>? streamController = StreamController<int>();/// StreamSink用作发射事件StreamSink<int>? get streamSink => streamController?.sink;/// 获取Stream用作事件监听Stream<int>? get streamData => streamController?.stream;/// 使用subscription来监听事件subscription = streamData?.listen((event) {// TODOprint("subscription listen event:${event}");});// 发射一个事件streamSink?.add(index);

Stream使用实例完整代码如下

import 'dart:async';import 'package:flutter/material.dart';class SteamDemoPage extends StatefulWidget {const SteamDemoPage({super.key});@overrideState<SteamDemoPage> createState() => _SteamDemoPageState();
}class _SteamDemoPageState extends State<SteamDemoPage> {int index = 0;int listenData = 0;/// 获取StreamSubscription用作管理监听,关闭暂停等StreamSubscription<int>? subscription;/// StreamControllerStreamController<int>? streamController = StreamController<int>();/// StreamSink用作发射事件StreamSink<int>? get streamSink => streamController?.sink;/// 获取Stream用作事件监听Stream<int>? get streamData => streamController?.stream;@overridevoid initState() {// TODO: implement initStatesuper.initState();streamController = StreamController<int>();/// 使用subscription来监听事件subscription = streamData?.listen((event) {// TODOprint("subscription listen event:${event}");setState(() {listenData = event;});});// 发射一个事件streamSink?.add(index);index++;}void testStream(BuildContext context) {// 发射一个事件streamSink?.add(index);index++;print("index -- ${index}");}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('HeroPage'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [Text('监听的listenData:${listenData}',style: TextStyle(fontSize: 16,color: Colors.black87,),),SizedBox(height: 30,),TextButton(onPressed: () {testStream(context);},child: Container(height: 46,width: 150,color: Colors.lightBlue,alignment: Alignment.center,child: Text('测试Stream',style: TextStyle(fontSize: 14,color: Colors.white,),),),),],),),);}
}

最后可以看到效果图,当点击按钮时候,监听的数值更新。
在这里插入图片描述

三、StreamBuilder

既然使用了Stream,我们可以StreamBuilder。如果我们再使用setState来刷新,则没有必要使用Stream了。

StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变化,并在数据发生变化时重新构建小部件树。

在StreamBuilder中,当数据流发生变化,Flutter框架会自动传递一个AsyncSnapshot,AsyncSnapshot对象包含Stream中的最新数据以及其他有关数据流信息,如是否处理链接状态、错误信息等。

StreamBuilder(stream: streamData,builder: (BuildContext ctx, AsyncSnapshot snapshot) {if (!snapshot.hasData) {return Text("没有数据");} else {return Text('监听的listenData:${snapshot.data}',style: TextStyle(fontSize: 16,color: Colors.black87,),);}},),

StreamBuilder的构造方法如下

const StreamBuilder({super.key,this.initialData,super.stream,required this.builder,}) : assert(builder != null);
  • initialData : 默认初始化数据
  • stream : stream事件流对象
  • builder : 负责根据不同状态创建对应ui的方法实现

StreamBuilder中的其他方法

  • afterConnected:返回一个AsyncSnapshot,当订阅了stream时会回调此AsyncSnapshot
  • afterData:返回一个AsyncSnapshot,当stream有事件触发时会回调此AsyncSnapshot
  • afterDisconnected:返回一个AsyncSnapshot,当取消订阅stream时会回调此AsyncSnapshot
  • afterDone:返回一个AsyncSnapshot,当stream被关闭时会回调此AsyncSnapshot
  • afterError:返回一个AsyncSnapshot,stream发生错误时会回调此AsyncSnapshot

四、使用StreamBuilder示例

在上面的示例中,我们可以将Text这个Widget通过StreamBuilder来包裹一下。
代码如下

StreamBuilder(stream: streamData,builder: (BuildContext ctx, AsyncSnapshot snapshot) {if (!snapshot.hasData) {return Text("没有数据");} else {return Text('监听的listenData:${snapshot.data}',style: TextStyle(fontSize: 16,color: Colors.black87,),);}},),

这里可以将示例中的StreamSubscription移除,暂时用不到了,可以找到StreamBuilder继承的StreamBuilderBase中已经创建了StreamSubscription,并且_subscribe

/// State for [StreamBuilderBase].
class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>> {StreamSubscription<T>? _subscription; // ignore: cancel_subscriptionslate S _summary;....void _subscribe() {if (widget.stream != null) {_subscription = widget.stream!.listen((T data) {setState(() {_summary = widget.afterData(_summary, data);});}, onError: (Object error, StackTrace stackTrace) {setState(() {_summary = widget.afterError(_summary, error, stackTrace);});}, onDone: () {setState(() {_summary = widget.afterDone(_summary);});});_summary = widget.afterConnected(_summary);}}void _unsubscribe() {if (_subscription != null) {_subscription!.cancel();_subscription = null;}}

使用StreamBuilder完整示例代码如下

import 'dart:async';import 'package:flutter/material.dart';class SteamDemoPage extends StatefulWidget {const SteamDemoPage({super.key});@overrideState<SteamDemoPage> createState() => _SteamDemoPageState();
}class _SteamDemoPageState extends State<SteamDemoPage> {int index = 0;int listenData = 0;/// 获取StreamSubscription用作管理监听,关闭暂停等// StreamSubscription<int>? subscription;/// StreamControllerStreamController<int>? streamController = StreamController<int>();/// StreamSink用作发射事件StreamSink<int>? get streamSink => streamController?.sink;/// 获取Stream用作事件监听Stream<int>? get streamData => streamController?.stream;@overridevoid initState() {// TODO: implement initStatesuper.initState();streamController = StreamController<int>();/// 使用subscription来监听事件// subscription = streamData?.listen((event) {//   // TODO//   print("subscription listen event:${event}");//   setState(() {//     listenData = event;//   });// });// 发射一个事件streamSink?.add(index);index++;}void testStream(BuildContext context) {// 发射一个事件streamSink?.add(index);index++;print("index -- ${index}");}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('HeroPage'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [StreamBuilder(stream: streamData,builder: (BuildContext ctx, AsyncSnapshot snapshot) {if (!snapshot.hasData) {return Text("没有数据");} else {return Text('监听的listenData:${snapshot.data}',style: TextStyle(fontSize: 16,color: Colors.black87,),);}},),SizedBox(height: 30,),TextButton(onPressed: () {testStream(context);},child: Container(height: 46,width: 150,color: Colors.lightBlue,alignment: Alignment.center,child: Text('测试Stream',style: TextStyle(fontSize: 14,color: Colors.white,),),),),],),),);}
}

https://brucegwo.blog.csdn.net/article/details/136232000

五、小结

flutter开发实战-StreamBuilder使用介绍及实例。

学习记录,每天不停进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/698629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode3035. 回文字符串的最大数量

Every day a Leetcode 题目来源&#xff1a;3035. 回文字符串的最大数量 解法1&#xff1a;哈希 排序 由于可以随意交换字母&#xff0c;先把所有字母都取出来&#xff0c;然后考虑如何填入各个字符串。 如果一个奇数长度字符串最终是回文串&#xff0c;那么它正中间的那…

精美的WordPress外贸独立站模板

WordPress外贸独立站主题 简洁实用的WordPress外贸独立站主题&#xff0c;适合时尚服装行业搭建wordpress企业官网使用。 https://www.jianzhanpress.com/?p4999 简洁wordpress独立站模板 绿色精美、简洁大气的wordpress外贸独立网站模板 https://www.jianzhanpress.com/?…

分享一个UE的SmoothStep小技巧

SmoothStep节点可以制作更平滑的动画&#xff0c;而如果将max参数作为值传入将value和min参数作为约束&#xff0c;则可以做出类似冲击波的渐变效果&#xff1a; 并且通过修改value与min之间的数值差&#xff0c;可以调节渐变。 这个技巧主要就是可以产生硬边。 比如我们可…

【黑马程序员】C++模版

20240214 文章目录 C泛型编程技术模版的概念 函数模版函数模版语法不使用模版的模版完成两个数交换使用模版的方式完成两个数的交换模版注意事项函数模版案列使用模版实现升序选择排序 模版函数和普通函数区别点调用规则 模版的局限性模版的通用性问题模版重载 类模板类模板语…

Redis和Mysql如何保证数据一致性

一般情况下&#xff0c;Redis用来实现应用和数据库之间读操作的缓存层&#xff0c;主要目的是减少数据 库IO&#xff0c;还可以提升数据的IO性能。 这是它的整体架构。 当应用程序需要去读取某个数据的时候&#xff0c;首先会先尝试去Redis里面加载&#xff0c;如果命中就 直…

【Java程序员面试专栏 数据结构】一 高频面试算法题:数组

一轮的算法训练完成后,对相关的题目有了一个初步理解了,接下来进行专题训练,以下这些题目就是汇总的高频题目,本篇主要聊聊数组,包括数组合并,滑动窗口解决最长无重复子数组问题,图形法解下一个排列问题,以及一些常见的二维矩阵问题,所以放到一篇Blog中集中练习 题目…

k8s(3)

目录 一.K8S的三种网络 flannel的三种模式: 在 node01 节点上操作&#xff1a; calico的 三种模式&#xff1a; flannel 与 calico 的区别&#xff1f; 二.CoreDNS 在所有 node 节点上操作&#xff1a; 在 master01 节点上操作&#xff1a; ​编辑 DNS 解析测试&#…

「C语言进阶1」动态内存分配

目录 一、动态内存分配是什么&#xff1f; 二、为什么需要动态内存分配&#xff1f; 三、怎么进行动态内存分配&#xff1f; 1. malloc 2. calloc 3. realloc a. realloc功能解析 b. 内存泄漏和内存块被截断问题 c. 总结 4. free 四、使用动态内存分配常见的问题 【面试题】 一…

如何将新标注的三元组数据转换成unicoqe可以处理的格式

目录 问题描述&#xff1a; 问题解决&#xff1a; 问题描述&#xff1a; 原始的标注的三元组格式如下&#xff1a; 需要转换的格式如下&#xff1a; tips:有一个小的难点&#xff1a; 1. 针对多三元组的情况&#xff0c;需要额外考虑 2. 最后一个样本&#xff0c;也记得需要…

QEMU之CPU虚拟化

概述 KVM是由以色列初创公司Qumranet在CPU推出硬件虚拟化之后开发的一个基于内核的虚拟机监控器。 KVM是一个虚拟化的统称方案&#xff0c;除了x86外&#xff0c;ARM等其他架构也有自己的方案&#xff0c;所以KVM的主体代码位于内核树virt/kvm目录下面&#xff0c;表示所有CP…

第九节HarmonyOS 常用基础组件25-QRCode

1、描述 用于显示单个二维码的组件。 2、接口 QRCode(value:string) 3、参数 参数名 参数类型 必填 描述 value string 是 二维码内容字符串。 4、属性 名称 参数类型 描述 color ResourceColor 设置二维码颜色。默认值&#xff1a;Color.Black backgroundCo…

阿里云优惠:优惠活动整理、云服务器价格、域名、数据库和优惠券领取

2024年阿里云优惠活动大全&#xff0c;包括阿里云服务器优惠活动清单、配置价格表、域名优惠活动、阿里云建站活动、阿里云优惠代金券免费领取、对象存储OSS活动、企业邮箱优惠、无影云电脑优惠、CDN特惠等等&#xff0c;阿里云百科aliyunbaike.com分享2024阿里云优惠活动大全_…

每日五道java面试题之spring篇(四)

目录&#xff1a; 第一题 Spring框架的设计目标&#xff0c;设计理念&#xff0c;和核心是什么&#xff1f;第二题. Spring由哪些模块组成&#xff1f;第三题. 详细讲解一下核心容器&#xff08;spring context应用上下文) 模块第四题.Spring框架中有哪些不同类型的事件第五题.…

网络中的进程监控

每个企业都有一些流程和程序来实现他们的业务目标&#xff0c;这同样适用于网络&#xff0c;网络中的进程监控是分析、处理和管理网络内发生的各种活动以提高网络性能和能力的做法。 网络中需要监控的基本进程 监视系统资源&#xff08;CPU 利用率、内存利用率、CPU 温度等&a…

【vue】如何打开别人编译后的vue项目

文件结构如下&#xff0c;编译后的文件放在dist中。 dist的文件结构大约如下&#xff0c;文件名称随项目 1.新建app.js文件 const express require(express);const app express();const port 8080;app.use(express.static(dist));app.listen(port, () > console.log); …

实用区块链应用:去中心化投票系统的部署与实施

一、需求分析背景 随着技术的发展&#xff0c;传统的投票系统面临着越来越多的挑战&#xff0c;如中心化控制、透明度不足和易受攻击等问题。为了解决这些问题&#xff0c;我们可以利用区块链技术去中心化、透明性和安全性来构建一个去中心化投票系统。这样的系统能够确保投票过…

六、回归与聚类算法 - 岭回归

目录 1、带有L2正则化的线性回归 - 岭回归 1.1 API 2、正则化程度的变化对结果的影响 3、波士顿房价预测 线性回归欠拟合与过拟合线性回归的改进 - 岭回归分类算法&#xff1a;逻辑回归模型保存与加载无监督学习&#xff1a;K-means算法 1、带有L2正则化的线性回归 - 岭回…

蓝桥杯C++竞赛常用库函数介绍

文章目录 前言一、二分查找1. 二分查找的前提2.binary_search函数3.lower_bound函数和upper_bound函数4.蓝桥杯例题 二、最值查找1. min和max函数2.min_element和max_element函数3.nth_element函数4.蓝桥杯例题 三、排序1.sort函数2.sort自定义比较函数,或lambda表达式(匿名函数…

流量分析——陇剑杯 2021【签到、jwt】

目录 签到1、攻击者正在进行的可能是什么协议的网络攻击 jwt1、该网站使用了______认证方式。前置知识&#xff1a;解&#xff1a; 2、黑客绕过验证使用的jwt中&#xff0c;id和username是3、黑客获取webshell之后&#xff0c;权限是什么4、黑客上传的恶意文件文件名是5、黑客在…

Sora没用上!国产AI创作恐怖电影:《生化危机:重生》下

Sora没用上&#xff01;国产AI创作恐怖电影&#xff1a;《生化危机&#xff1a;重生》下 丧尸围城&#xff0c;世界沦陷&#xff0c;爱丽丝是拯救这个世界的最后一剂解药&#xff0c;然而。。。 《生化危机&#xff1a;重生》&#xff08;下&#xff09;&#xff1a;在战斗的最…