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 的任何一种实现中,…...
嵌入式图像处理实战:中值滤波 vs 均值滤波在STM32上的性能对比(附代码)
嵌入式图像处理实战:中值滤波 vs 均值滤波在STM32上的性能对比(附代码) 在机器人视觉或工业检测系统中,一个突如其来的像素噪点可能导致整个识别算法崩溃。我曾亲眼见证过某产线机械臂因图像传感器受到电磁干扰,将正常…...
不会画画也能创作!梦幻动漫魔法工坊新手入门全攻略
不会画画也能创作!梦幻动漫魔法工坊新手入门全攻略 1. 为什么你需要这个工具 你是否曾经有过这样的经历:脑海中浮现出一个绝妙的动漫角色形象,却因为不会画画而无法将它呈现出来?或者想为社交媒体创作独特的二次元头像ÿ…...
5步清理60GB重复视频:Krokiet视频查重工具全攻略
5步清理60GB重复视频:Krokiet视频查重工具全攻略 【免费下载链接】czkawka 一款跨平台的重复文件查找工具,可用于清理硬盘中的重复文件、相似图片、零字节文件等。它以高效、易用为特点,帮助用户释放存储空间。 项目地址: https://gitcode.…...
cv_resnet101_face-detection_cvpr22papermogface 模型部署的网络安全考量:防范403 Forbidden等常见攻击
cv_resnet101_face-detection_cvpr22papermogface 模型部署的网络安全考量:防范403 Forbidden等常见攻击 把一个人脸检测模型,比如 cv_resnet101_face-detection_cvpr22papermogface,部署成一个Web API,这事儿听起来挺酷的。想象…...
卷积计算常见误区解析:为什么你的结果和理论值对不上?
卷积计算常见误区解析:为什么你的结果和理论值对不上? 在图像处理和深度学习领域,卷积操作是基础中的基础。但令人惊讶的是,即使是经验丰富的开发者,在实际编码时也常常遇到计算结果与预期不符的情况。这就像做菜时严格…...
QT5实战:如何用QTreeView打造层级分明的下拉菜单(附完整代码)
QT5实战:用QTreeView构建层级下拉菜单的工程化实现 在桌面应用开发中,标准的下拉菜单往往难以应对复杂的层级数据展示需求。想象一下文件浏览器中的树形目录、多级分类的商品筛选器,或是组织架构中的部门-人员选择场景——这些都需要更强大的…...
实测分享:圣女司幼幽-造相Z-Turbo生成高质量角色图片案例
实测分享:圣女司幼幽-造相Z-Turbo生成高质量角色图片案例 1. 引言:当AI画笔遇上经典角色 如果你是《牧神记》的读者,或者对国风仙侠角色情有独钟,那么“圣女司幼幽”这个名字一定不会陌生。她清冷孤傲、手持长剑的形象早已深入人…...
Pylint魔法方法验证:10个技巧确保特殊方法符合Python规范的终极指南
Pylint魔法方法验证:10个技巧确保特殊方法符合Python规范的终极指南 【免费下载链接】pylint Its not just a linter that annoys you! 项目地址: https://gitcode.com/gh_mirrors/pyl/pylint Python开发者们,你是否曾为魔法方法(dund…...
别再只用scatter了!用Matlab绘制密度散点图,让你的数据分布一目了然(附TheColor配色方案)
突破数据可视化瓶颈:Matlab密度散点图实战指南 当你面对数十万个数据点时,传统的散点图往往会变成一团模糊的噪点,重要分布特征完全被掩盖。这种场景下,密度散点图就像给你的数据装上了X光机,让隐藏的模式和结构清晰可…...
麦克风效率革命:MicMute让静音操作提速90%的终极体验升级
麦克风效率革命:MicMute让静音操作提速90%的终极体验升级 【免费下载链接】MicMute Mute default mic clicking tray icon or shortcut 项目地址: https://gitcode.com/gh_mirrors/mi/MicMute 你是否经历过线上会议中手忙脚乱寻找静音按钮的窘迫?…...
