当前位置: 首页 > news >正文

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首页&#xff0c;一系列的弹窗就会弹出。如果不做处理就会导致弹窗堆积的全部弹出&#xff0c;严重影响用户体验。 如果多个弹窗中又有判断逻辑&#xff0c;根据点击后需要弹出另一个弹窗&#xff0c;这…...

1290.二进制链表转整数

给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。 请你返回该链表所表示数字的 十进制值 。 示例 1&#xff1a; 输入&#xff1a;head [1,0,1] 输出&#xff1a;5 解释&#xff1a;二进制数 (101) 转化为十进制…...

P8803 [蓝桥杯 2022 国 B] 费用报销

P8803 [蓝桥杯 2022 国 B] 费用报销 分析 最值问题——DP 题意分析&#xff1a;从N张票据中选&#xff0c;且总价值不超过M的票据的最大价值&#xff08;背包问题&#xff09; K天限制 一、处理K天限制&#xff1a; 1.对于输入的是月 日的格式&#xff0c;很常用的方式是…...

【Android】Kotlin学习之Lambda表达式

java和kotlin对比 Lambda语法 Lambda隐形参数 it 也可以不使用指定的名称it, 可以 自定义 Lambda 使用下划线...

YOLOv5-7.0改进(四)添加EMA注意力机制

前言 关于网络中注意力机制的改进有很多种&#xff0c;本篇内容从EMA注意力机制开始&#xff01; 往期回顾 YOLOv5-7.0改进&#xff08;一&#xff09;MobileNetv3替换主干网络 YOLOv5-7.0改进&#xff08;二&#xff09;BiFPN替换Neck网络 YOLOv5-7.0改进&#xff08;三&…...

TCP协议的确认应答机制

TCP&#xff08;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的、基于字节流的传输层协议&#xff0c;它在网络通信中扮演着至关重要的角色。其中&#xff0c;确认应答机制是TCP协议中的一个核心概念&#xff0c;它确保了数据的可靠传输。本文将详细介绍J…...

【论文阅读笔记】MAS-SAM: Segment Any Marine Animal with Aggregated Features

1.论文介绍 MAS-SAM: Segment Any Marine Animal with Aggregated Features MAS-SAM&#xff1a;利用聚合特征分割任何海洋动物 Paper Code(空的) 2.摘要 最近&#xff0c;分割任何模型&#xff08;SAM&#xff09;在生成高质量的对象掩模和实现零拍摄图像分割方面表现出卓越…...

C语言中的精确宽度类型

概述 在 C 语言标准库 <stdint.h> 中定义了一系列精确宽度的整数类型&#xff0c;这些类型保证了它们的位数宽度&#xff0c;从而允许编写跨平台的可移植代码。以下是一些常用的精确宽度整数类型&#xff1a; int8_t: 8位有符号整数uint8_t: 8位无符号整数int16_t: 16位…...

大数据比赛-环境搭建(一)

1、安装VMware Workstation 链接&#xff1a;https://pan.baidu.com/s/1IvSFzpnQFl3svWyCGRtEmg 提取码&#xff1a;ukpo 内有安装包及破解方式&#xff0c;安装教程。 2、下载Ubuntu系统 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 (aliyun.com) 点击下载&#xff…...

微信小程序原生组件使用

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类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;8375 标注数量(xml文件个数)&#xff1a;8375 标注数量(txt文件个数)&#xff1a;8375 标注…...

2024HW Linux应急响应基础学习

首先展示关于Linux的关键目录&#xff0c;这是应急响应查看的关键&#xff1a; 常用命令 top //查看进程资源的占用情况 ps -aux //查看进程 直接写ps aux也可以 netstat -antpl //查看网络连接 ls -alh /proc/pid //查看某个pid对应的可执行程序 pid记得修改 lsof /…...

烽火三十六技丨网络资产安全治理平台新版本发布,一文看懂四大核心优势

云计算、移动互联网、物联网等技术飞速发展&#xff0c;网络环境愈发开放互联&#xff0c;原有的资产管理方式已难以适应当下的变化。同时&#xff0c;网络资产需求的突发性和人为疏忽&#xff0c;也时常导致资产数量不明、类型模糊、安全漏洞检查不全面等问题。因此&#xff0…...

视频资源汇聚平台常见的几种接入方式

视频资源汇聚平台 视频汇聚平台可以实现海量资源的接入、汇聚、存储、处理、分析、运维等&#xff0c;平台具备轻量化接入能力&#xff0c;可支持多协议方式接入&#xff0c;包括主流标准协议GB28181、RTSP、ONVIF、RTMP、FLV、WEBSOCKET等&#xff0c;以及厂家私有协议与SDK接…...

LeetCode 212.单词搜索II

https://leetcode.cn/problems/word-search-ii/description/?envTypestudy-plan-v2&envIdtop-interview-150 文章目录 题目描述解题思路代码实现 题目描述 给定一个 m x n 二维字符网格 board 和一个单词&#xff08;字符串&#xff09;列表 words&#xff0c; 返回所有二…...

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代码+结果+可视化图)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了2024数维杯数学建模挑战赛生物质和煤共热解问题的研究完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 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绘图功能探索&#xff1a; 1、保持人物形象一致&#xff0c;适配更多的表情、动作 2、改变穿衣风格 3、小女孩的不同年龄段展示 4、不同社交平台的个性头像创作 如果不会写代码&#xff0c;可以问GPT。使用地址&#xff1a;我的GPT4 视频&#xff0c;B站会发&#…...

程序环境和预处理、编译链接过程、编译的几个阶段、运行环境、预定义符号等的介绍

文章目录 前言一、程序的翻译环境和执行环境二、编译链接过程三、编译的几个阶段四、运行环境五、预定义符号总结 前言 程序环境和预处理、编译链接过程、编译的几个阶段、运行环境、预定义符号的介绍。 一、程序的翻译环境和执行环境 在 ANSI C 的任何一种实现中&#xff0c…...

FeignClient调用接口参数为null?可能是这个阿里规范在作怪

FeignClient参数丢失陷阱&#xff1a;从布尔类型序列化到企业级解决方案 微服务架构下&#xff0c;FeignClient作为声明式HTTP客户端&#xff0c;其简洁的API设计让远程调用如同本地方法般自然。但当你的DTO对象中那个精心设计的isActive字段在服务端始终显示为null时&#xff…...

ARMv8虚拟化性能优化指南:TLB的ASID和VMID到底怎么用?

ARMv8虚拟化性能优化指南&#xff1a;TLB的ASID和VMID实战解析 虚拟化技术在云计算和容器化场景中已成为基础设施的核心支柱&#xff0c;而ARM架构凭借其能效优势&#xff0c;正逐步渗透到数据中心领域。但在高密度虚拟化环境中&#xff0c;内存访问性能往往成为瓶颈——我们曾…...

从原理图到实测:手把手打造Ti电量计通讯盒EV2400

1. 为什么需要自制EV2400通讯盒 搞锂电池开发的朋友应该都熟悉Ti的电量计芯片&#xff0c;比如bq系列。这些芯片需要通过I2C/SMBus或者HDQ接口与电脑通信&#xff0c;这时候就需要一个通讯盒作为桥梁。官方EV2400虽然好用&#xff0c;但价格实在不亲民&#xff0c;而且功能上可…...

万象视界灵坛惊艳效果展示:同一张宠物图在‘金毛犬’‘幼犬’‘户外玩耍’‘毛发蓬松’多维排序

万象视界灵坛惊艳效果展示&#xff1a;同一张宠物图在"金毛犬""幼犬""户外玩耍""毛发蓬松"多维排序 1. 效果展示开场 今天我要向大家展示万象视界灵坛这个神奇工具的实际效果。它就像一个视觉魔法师&#xff0c;能够深入理解图片中的…...

C++的std--ranges中的验证编译期

C20引入的std::ranges库彻底改变了范围操作的方式&#xff0c;其中编译期验证机制是其最强大的特性之一。这种机制允许开发者在编译阶段捕获潜在错误&#xff0c;显著提升了代码的健壮性和性能。本文将深入探讨std::ranges中编译期验证的核心机制及其实际应用价值。编译时概念检…...

mbed OS双极性步进电机驱动库设计与应用

1. 项目概述BipoarStepperMotor 是一个面向 ARM Cortex-M 系统、专为 mbed OS 平台设计的双极性步进电机驱动库。该库不依赖特定硬件抽象层&#xff08;HAL&#xff09;变体&#xff0c;而是基于 mbed OS 提供的标准 DigitalOut 和 PwmOut 接口构建&#xff0c;具备良好的跨平台…...

Simulink SVPWM模块输出对不上?别慌,可能是这两个参数没设对(附24V电机FOC仿真案例)

Simulink SVPWM模块输出差异排查指南&#xff1a;从参数配置到波形修正 引言 在电机控制系统的仿真与开发过程中&#xff0c;Simulink的SVPWM模块是工程师们常用的工具之一。然而&#xff0c;许多开发者在对比自带模块与自建模型输出时&#xff0c;经常会遇到令人困惑的波形不一…...

Spring AI 2025实战:从零构建企业级智能问答系统

1. 为什么企业需要智能问答系统&#xff1f; 想象一下这样的场景&#xff1a;新员工入职第一天&#xff0c;面对公司庞杂的知识库手足无措&#xff1b;客服部门每天重复回答相同的基础问题&#xff1b;技术团队在查找内部文档时浪费大量时间。这些都是我亲身经历过的痛点&#…...

华帝COO韩伟:破局立新,“全域协同、效率革命”迎战行业新周期

3月30日&#xff0c;华帝“人生净界”新品发布会在杭州举行。这场发布会&#xff0c;不仅官宣全新代言人张凌赫并重磅发布非遗美学瓷话套系&#xff0c;清晰地传递出华帝面向未来的战略航向。发布会上&#xff0c;华帝股份副总裁兼COO韩伟深度剖析厨电行业变革趋势&#xff0c;…...

Youtu-Parsing模型C盘空间优化部署:清理与迁移实战指南

Youtu-Parsing模型C盘空间优化部署&#xff1a;清理与迁移实战指南 你是不是也遇到过这种情况&#xff1f;兴致勃勃地在Windows电脑上部署Youtu-Parsing这类大模型&#xff0c;准备大干一场&#xff0c;结果没跑几天&#xff0c;C盘就亮起了刺眼的红色警告。系统盘空间告急&am…...