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://xiahunao.cn/news/2803097.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Vulnhub-OSCP

信息收集 # nmap -sn 192.168.1.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-07 17:49 CST Nmap scan report for 192.168.1.1 Host is up (0.00052s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan report for 192.168.1.…

#LLM入门|Prompt#1.8_聊天机器人_Chatbot

聊天机器人设计 以会话形式进行交互&#xff0c;接受一系列消息作为输入&#xff0c;并返回模型生成的消息作为输出。原本设计用于简便多轮对话&#xff0c;但同样适用于单轮任务。 设计思路 个性化特性&#xff1a;通过定制模型的训练数据和参数&#xff0c;使机器人拥有特…

安卓手机修改 设置永不锁屏 屏幕永不超时 设置自动锁屏时间 从不 无源码修改系统设置 无需反编译

项目需要 。个别手机系统是的 自动锁屏时间 是没有 永不这个选项的&#xff0c;最多是30分钟。 根据需要。借鉴别人代码&#xff0c;修改&#xff0c;实现了可以在无源码 不反编译系统的情况下。实现屏幕用不锁屏&#xff0c;永不超时的需求&#xff0c; 有需要的小伙伴可以私…

Jenkins的使用GIT(4)

Jenkins的使用GIT 20211002 我们使用 Jenkins 集成外部 Git 仓库&#xff0c;实现对真实代码的拉取和构建。在这里&#xff0c;我们选用 Coding/Github/Gitee 等都可以作为我们的代码源 1 生成公钥私钥 首先&#xff0c;我们先来配置公钥和私钥。这是 Jenkins 访问 Git 私有库…

SparkSQL学习03-数据读取与存储

文章目录 1 数据的加载1.1 方式一&#xff1a;spark.read.format1.1.1读取json数据1.1.2 读取jdbc数据 1.2 方式二&#xff1a;spark.read.xxx1.2.1 读取json数据1.2.2 读取csv数据1.2.3 读取txt数据1.2.4 读取parquet数据1.2.5 读取orc数据1.2.6 读取jdbc数据 2 数据的保存2.1…

vue使用luckysheet时报错window.luckysheet.destroy is not a function

这里写自定义目录标题 vue使用luckysheet时报错window.luckysheet.destroy is not a function解决办法 vue使用luckysheet时报错window.luckysheet.destroy is not a function 按照教程 luckysheet教程: link 将需要的资源进行本地引入。 本地预览excel正常&#xff0c;但是放…

Tomcat 学习之 Filter 过滤器

目录 1 Filter 介绍 2 Filter 的生命周期 3 Filter 和 FilterChain 4 Filter 拦截过程 5 FilterConfig 6 Filter 使用 1 Filter 介绍 在 Tomcat 中&#xff0c;Filter 是一种用于拦截请求和过滤响应的组件&#xff0c;可以在请求到达 Servlet 之前或响应离开 Servlet 之后…

视频的语音转成文字字幕?这3个方法让你实现

随着网络的普及&#xff0c;越来越多的学生选择在网上观看辅导视频&#xff0c;以便随时随地学习。然而&#xff0c;整理这些视频中的教学笔记却成为了一个让人头疼的问题。传统的边看边记录的方式不仅费时费力&#xff0c;还容易遗漏重要信息。那么&#xff0c;有没有一种方法…

Spring Boot application.properties和application.yml文件的配置

在Spring Boot中&#xff0c;application.properties 和 application.yml 文件用于配置应用程序的各个方面&#xff0c;如服务器端口、数据库连接、日志级别等。这两个文件是Spring Boot的配置文件&#xff0c;位于 src/main/resources 目录下。 application.properties 示例 …

Jmeter基础(1) Mac下载安装启动

目录 Jmeter下载安装启动下载启动 Jmeter下载安装启动 注意⚠️&#xff1a;使用jmeter需要有java环境 下载 官网下载地址&#xff1a;https://jmeter.apache.org/ 会看到这里有两个版本&#xff0c;那么有什么区别么&#xff1f; Binaries是可执行版&#xff0c;直接下载解…

PostgreSQL 的实体化视图介绍

PostgreSQL 实体化视图提供一个强大的机制&#xff0c;通过预先计算并将查询结果集存储为物理表来提高查询性能。本教程将使用 DVD Rental Database 数据库作为演示例子&#xff0c;指导你在 PostgreSQL中创建实体化视图。 了解实体化视图 实体化视图是查询结果集的快照&…

网站访问免费升级成 HTTPS

步骤一&#xff1a;获取SSL证书 要将网站访问改为HTTPS&#xff0c;首先需要获取一个免费SSL证书。SSL证书是由受信任的证书颁发机构&#xff08;CA&#xff09;签发的数字证书&#xff0c;用于验证网站的身份并加密与用户的通信。可以通过购买或免费获取SSL证书。一些常见的免…

腾讯云宝塔Linux安装Mysql5.7

一、下载官方mysql包 wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm二、安装mysql包 rpm -ivh mysql-community-release-el7-5.noarch.rpm三、安装mysql yum install mysql-community-server -y四、启动数据库 systemctl start mysqld.service…

JNDI注入+RMI流程复现代码调试

前置知识 javax.naming&#xff1a;主要用于命名操作&#xff0c;它包含了命名服务的类和接口&#xff0c;该包定义了Context接口和InitialContext类&#xff1b;javax.naming.directory&#xff1a;主要用于目录操作&#xff0c;它定义了DirContext接口和InitialDir- Context…

使用jconsole监控SpringbootJVM(JDK11)

SpringBoot启动时增加参数&#xff1a; java -Djava.rmi.server.hostname服务器IP -Dcom.sun.management.jmxremotetrue \ -Dcom.sun.management.jmxremote.port1099 \ -Dcom.sun.management.jmxremote.rmi.port1099 \ -Dcom.sun.management.jmxremote.authenticatefalse \ -D…

C 嵌入式系统设计模式 10:中介者模式

本书的原著为&#xff1a;《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》&#xff0c;讲解的是嵌入式系统设计模式&#xff0c;是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述访问硬件的设计模式之三&…

hash,以及数据结构——map容器

1.hash是什么&#xff1f; 定义&#xff1a;hash,一般翻译做散列、杂凑&#xff0c;或音译为哈希&#xff0c;是把任意长度的输入&#xff08;又叫做预映射pre-image&#xff09;通过散列算法变换成固定长度的输出&#xff0c; 该输出就是散列值。这种转换是一种压缩映射&…

谷歌浏览器文件下载不了的问题

问题: 谷歌浏览器测试环境a标签下载附件没问题,但是另一个环境下载闪了一下但是没有下载. 原因:测试环境http,附件下载链接是http,但是另一个环境网页地址是https,附件下载链接是http. Chrome将开始阻止“安全页面”&#xff08;HTTPS&#xff09;上所有“非安全子资源”&#…

BeikeShop跨境电商PHP商城源码

BeikeShop 一款开源好用的跨境电商系统&#xff0c;BeikeShop 是基于 Laravel 开发的一款开源商城系统主要面向外贸/跨境电商行业提供商品管理、订单管理、会员管理、支付、物流、系统管理等功能。 插件市场支持个人免签 BeikeShop系统亮点 1、系统代码100%开源 2、代码分层…

RabbitMQ开启MQTT协议支持

1&#xff09;RabbitMQ启用MQTT插件 rootmq:/# rabbitmq-plugins enable rabbitmq_mqtt Enabling plugins on node rabbitmq: rabbitmq_mqtt The following plugins have been configured:rabbitmq_managementrabbitmq_management_agentrabbitmq_mqttrabbitmq_web_dispatch Ap…