Flutter弹窗链-顺序弹出对话框
效果

前言
弹窗的顺序执行在App中是一个比较常见的应用场景。比如进入App首页,一系列的弹窗就会弹出。如果不做处理就会导致弹窗堆积的全部弹出,严重影响用户体验。
如果多个弹窗中又有判断逻辑,根据点击后需要弹出另一个弹窗,这个弹窗优先级更高,需要在当前弹出框关闭后弹出,又添加了复杂度了,所以才会有需要管理多个弹窗的展示需求。
实现
- 采用方式是拦截器法
/// 源码:https://github.com/yixiaolunhui/flutter_xy
/// 链式拦截器。
abstract class ChainInterceptor {/// 拦截器执行方法。void intercept(ChainHandler chain);
}/// 链
abstract class Chain {/// 将拦截器添加到链中。/// 如果提供了 [index],则在指定的索引处添加拦截器。/// 否则,将拦截器添加到链的末尾。void addChain(ChainInterceptor interceptor, {int? index});/// 执行链void proceed();
}/// 链状态监听器。
abstract class ChainStatusListener {/// 当链状态发生变化时调用。/// [isChainEnd] 表示链是否已经执行完毕。void onStatusChange(bool isChainEnd);
}/// 构建和执行链帮助类
class ChainHelper {static Builder builder() {return Builder();}
}/// 用于构建链的构建器类。
class Builder {final ChainHandler _chainHandler = ChainHandler();/// 将拦截器添加到链中。////// 如果提供了 [index],则在指定的索引处添加拦截器。/// 否则,将拦截器添加到链的末尾。Builder addChain(ChainInterceptor interceptor, {int? index}) {_chainHandler.addChain(interceptor, index: index);return this;}/// 设置链的状态监听器。Builder setChainStatusListener(ChainStatusListener chainStatusListener) {_chainHandler.setChainStatusListener(chainStatusListener);return this;}/// 获取 [ChainManager] 实例。ChainHandler get chainHandler => _chainHandler;/// 执行链。void execute() {_chainHandler.proceed();}
}/// 链管理类
class ChainHandler implements Chain {final _chains = <ChainInterceptor>[];int _index = 0;ChainStatusListener? _statusListener;/// 设置链的状态监听器。void setChainStatusListener(ChainStatusListener chainStatusListener) {_statusListener = chainStatusListener;}/// 将拦截器添加到链中。////// 如果提供了 [index],则在指定的索引处添加拦截器。/// 否则,将拦截器添加到链的末尾。@overridevoid addChain(ChainInterceptor interceptor, {int? index}) {if (index != null) {_chains.insert(index, interceptor);} else {_chains.add(interceptor);}}/// 获取链中拦截器的数量。int getChainCount() => _chains.length;/// 当前索引int get currentIndex => _index;/// 执行链。////// 通知 [ChainStatusListener] 链状态的变化。/// 如果链已经执行完毕,则清空链。@overridevoid proceed() {bool isChainEnd = _index >= _chains.length;_statusListener?.onStatusChange(isChainEnd);if (isChainEnd) {clear();return;}_chains[_index++].intercept(this);}/// 清空链void clear() {_chains.clear();_index = 0;}
}
使用
- 定义多个弹出框
/// 源码:https://github.com/yixiaolunhui/flutter_xy
///第1个弹窗
class OneDialog implements ChainInterceptor {@overridevoid intercept(ChainHandler chain) {showDialog(builder: (BuildContext context) {return AlertDialog(title: const Text('第1个弹出框'),content: const Text('这个是一个弹出框的内容文案'),actions: [TextButton(onPressed: () {Navigator.pop(context);chain.proceed();},child: const Text('取消'),),TextButton(onPressed: () {Navigator.pop(context);chain.proceed();},child: const Text('确认'),),],);},context: App.get().context,);}
}///第2个弹窗
class TwoDialog implements ChainInterceptor {@overridevoid intercept(ChainHandler chain) {showDialog(context: App.get().context,builder: (BuildContext context) {return AlertDialog(title: const Text('第2个弹出框'),content: const Text('这个是一个弹出框的内容文案'),actions: [TextButton(onPressed: () {Navigator.pop(context);chain.proceed();},child: const Text('取消'),),TextButton(onPressed: () {Navigator.pop(context);//这里模拟插入新的弹出框,一般场景是点击按钮后,请求网络然后需要弹出新的弹出框chain.addChain(OtherDialog(), index: chain.currentIndex);chain.proceed();},child: const Text('添加其他弹出框'),),],);},);}
}///第3个弹窗
class ThreeDialog implements ChainInterceptor {@overridevoid intercept(ChainHandler chain) {showDialog(context: App.get().context,builder: (BuildContext context) {return AlertDialog(title: const Text('第3个弹出框'),content: const Text('这个是一个弹出框的内容文案'),actions: [TextButton(onPressed: () {Navigator.pop(context);chain.proceed();},child: const Text('取消'),),TextButton(onPressed: () {Navigator.pop(context);chain.addChain(OtherDialog(), index: chain.currentIndex);chain.proceed();},child: const Text('添加其他弹出框'),),],);},);}
}///第4个弹窗
class FourDialog implements ChainInterceptor {@overridevoid intercept(ChainHandler chain) {showDialog(builder: (BuildContext context) {return AlertDialog(title: const Text('第4个弹出框'),content: const Text('这个是一个弹出框的内容文案'),actions: [TextButton(onPressed: () {Navigator.pop(context);chain.proceed();},child: const Text('取消'),),TextButton(onPressed: () {Navigator.pop(context);chain.proceed();},child: const Text('确认'),),],);},context: App.get().context,);}
}///其他弹窗(用于案例中插入用)
class OtherDialog implements ChainInterceptor {@overridevoid intercept(ChainHandler chain) {showDialog(context: App.get().context,builder: (BuildContext context) {return AlertDialog(title: const Text('其他弹出框'),content: const Text('这个是一个弹出框的内容文案'),actions: [TextButton(onPressed: () {Navigator.pop(context);chain.proceed();},child: const Text('取消'),),TextButton(onPressed: () {Navigator.pop(context);chain.proceed();},child: const Text('确认'),),],);},);}
}
- 如何使用
class ChainDialogPage extends StatefulWidget {const ChainDialogPage({super.key});@overrideState<ChainDialogPage> createState() => _ChainDialogPageState();
}class _ChainDialogPageState extends State<ChainDialogPage> {var chainHelper = ChainHelper.builder();@overridevoid initState() {super.initState();}//显示对话框void showDialogs() {chainHelper.addChain(OneDialog());chainHelper.addChain(TwoDialog());chainHelper.addChain(ThreeDialog());chainHelper.addChain(FourDialog());chainHelper.execute();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: XYAppBar(title: "Flutter弹框链",onBack: () {Navigator.pop(context);},),body: SafeArea(child: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [ElevatedButton(onPressed: () {showDialogs();},child: const Text("启动弹框链"),),],),),),);}
}
运行后效果

详情:github.com/yixiaolunhui/flutter_xy
相关文章:
Flutter弹窗链-顺序弹出对话框
效果 前言 弹窗的顺序执行在App中是一个比较常见的应用场景。比如进入App首页,一系列的弹窗就会弹出。如果不做处理就会导致弹窗堆积的全部弹出,严重影响用户体验。 如果多个弹窗中又有判断逻辑,根据点击后需要弹出另一个弹窗,这…...
1290.二进制链表转整数
给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。 请你返回该链表所表示数字的 十进制值 。 示例 1: 输入:head [1,0,1] 输出:5 解释:二进制数 (101) 转化为十进制…...
P8803 [蓝桥杯 2022 国 B] 费用报销
P8803 [蓝桥杯 2022 国 B] 费用报销 分析 最值问题——DP 题意分析:从N张票据中选,且总价值不超过M的票据的最大价值(背包问题) K天限制 一、处理K天限制: 1.对于输入的是月 日的格式,很常用的方式是…...
【Android】Kotlin学习之Lambda表达式
java和kotlin对比 Lambda语法 Lambda隐形参数 it 也可以不使用指定的名称it, 可以 自定义 Lambda 使用下划线...
YOLOv5-7.0改进(四)添加EMA注意力机制
前言 关于网络中注意力机制的改进有很多种,本篇内容从EMA注意力机制开始! 往期回顾 YOLOv5-7.0改进(一)MobileNetv3替换主干网络 YOLOv5-7.0改进(二)BiFPN替换Neck网络 YOLOv5-7.0改进(三&…...
TCP协议的确认应答机制
TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层协议,它在网络通信中扮演着至关重要的角色。其中,确认应答机制是TCP协议中的一个核心概念,它确保了数据的可靠传输。本文将详细介绍J…...
【论文阅读笔记】MAS-SAM: Segment Any Marine Animal with Aggregated Features
1.论文介绍 MAS-SAM: Segment Any Marine Animal with Aggregated Features MAS-SAM:利用聚合特征分割任何海洋动物 Paper Code(空的) 2.摘要 最近,分割任何模型(SAM)在生成高质量的对象掩模和实现零拍摄图像分割方面表现出卓越…...
C语言中的精确宽度类型
概述 在 C 语言标准库 <stdint.h> 中定义了一系列精确宽度的整数类型,这些类型保证了它们的位数宽度,从而允许编写跨平台的可移植代码。以下是一些常用的精确宽度整数类型: int8_t: 8位有符号整数uint8_t: 8位无符号整数int16_t: 16位…...
大数据比赛-环境搭建(一)
1、安装VMware Workstation 链接:https://pan.baidu.com/s/1IvSFzpnQFl3svWyCGRtEmg 提取码:ukpo 内有安装包及破解方式,安装教程。 2、下载Ubuntu系统 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 (aliyun.com) 点击下载ÿ…...
微信小程序原生组件使用
1、video组件使用 <view class"live-video"><video id"myVideo" src"{{videoSrc}}" bindplay"onPlay" bindfullscreenchange"fullScreenChange" controls object- fit"contain"> </video&g…...
[数据集][目标检测]纸箱子检测数据集VOC+YOLO格式8375张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):8375 标注数量(xml文件个数):8375 标注数量(txt文件个数):8375 标注…...
2024HW Linux应急响应基础学习
首先展示关于Linux的关键目录,这是应急响应查看的关键: 常用命令 top //查看进程资源的占用情况 ps -aux //查看进程 直接写ps aux也可以 netstat -antpl //查看网络连接 ls -alh /proc/pid //查看某个pid对应的可执行程序 pid记得修改 lsof /…...
烽火三十六技丨网络资产安全治理平台新版本发布,一文看懂四大核心优势
云计算、移动互联网、物联网等技术飞速发展,网络环境愈发开放互联,原有的资产管理方式已难以适应当下的变化。同时,网络资产需求的突发性和人为疏忽,也时常导致资产数量不明、类型模糊、安全漏洞检查不全面等问题。因此࿰…...
视频资源汇聚平台常见的几种接入方式
视频资源汇聚平台 视频汇聚平台可以实现海量资源的接入、汇聚、存储、处理、分析、运维等,平台具备轻量化接入能力,可支持多协议方式接入,包括主流标准协议GB28181、RTSP、ONVIF、RTMP、FLV、WEBSOCKET等,以及厂家私有协议与SDK接…...
LeetCode 212.单词搜索II
https://leetcode.cn/problems/word-search-ii/description/?envTypestudy-plan-v2&envIdtop-interview-150 文章目录 题目描述解题思路代码实现 题目描述 给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二…...
android 蓝牙技术 学习记录
一 。蓝牙介绍 蓝牙可以分为 经典蓝牙-----》传统蓝牙(BT 1.0/2.0/2.1)和高速蓝牙(BT3.0) 低功耗蓝牙 ----》BLE(BLE 4.0/4.1/4.2/5.0./5.1/5.2)和 Bluetooth Mesh 关于蓝牙协议。除开Mesh大致可以分为3层: App:上层协议有很多,例如ANP,HOGP,FTMP 等等 host:中…...
2024数维杯数学建模B题完整论文讲解(含每一问python代码+结果+可视化图)
大家好呀,从发布赛题一直到现在,总算完成了2024数维杯数学建模挑战赛生物质和煤共热解问题的研究完整的成品论文。 本论文可以保证原创,保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 B题论…...
二叉树进阶 --- 中
目录 1. find 的递归实现 2. insert 的递归实现 3. erase 的递归实现 3.1. 被删除的节点右孩子为空 3.2. 被删除的节点左孩子为空 3.3. 被删除的节点左右孩子都不为空 4. 析构函数的实现 5. copy constructor的实现 6. 赋值运算符重载 7. 搜索二叉树的完整实现 1. fi…...
ChatGPT DALL-E绘图,制作各种表情包,实现穿衣风格的自由切换
DALL-E绘图功能探索: 1、保持人物形象一致,适配更多的表情、动作 2、改变穿衣风格 3、小女孩的不同年龄段展示 4、不同社交平台的个性头像创作 如果不会写代码,可以问GPT。使用地址:我的GPT4 视频,B站会发&#…...
程序环境和预处理、编译链接过程、编译的几个阶段、运行环境、预定义符号等的介绍
文章目录 前言一、程序的翻译环境和执行环境二、编译链接过程三、编译的几个阶段四、运行环境五、预定义符号总结 前言 程序环境和预处理、编译链接过程、编译的几个阶段、运行环境、预定义符号的介绍。 一、程序的翻译环境和执行环境 在 ANSI C 的任何一种实现中,…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
