Flutter 彈窗隊列管理:支持優先級的線程安全通用彈窗隊列系統

在復雜的 Flutter 應用開發中,彈窗管理是一個常見難題。手動管理彈窗的顯示順序和條件判斷不僅繁瑣,還容易出錯。為此,我們實現了一個支持優先級的線程安全通用彈窗隊列管理系統。它能夠自動管理彈窗的顯示順序,支持條件判斷,并且可以靈活地在任何地方調用。

一、需求分析

  1. 支持彈窗隊列:按順序顯示多個彈窗。
  2. 條件判斷:彈窗顯示前可進行條件判斷。
  3. 線程安全:確保在多線程環境下操作安全。
  4. 通用性:可在任何地方調用,不限于 StatefulWidget
  5. 優先級支持:支持彈窗優先級,高優先級彈窗優先顯示。

二、實現思路

  1. 單例模式:全局只有一個隊列管理實例。
  2. 線程安全:使用 synchronized 包確保操作安全。
  3. 優先級排序:彈窗按優先級排序,高優先級先顯示。
  4. 獨立函數:提供獨立的 showQueueDialog 函數,方便調用。

三、代碼實現

1. 彈窗隊列管理類

import 'dart:async';import 'package:flutter/material.dart';const _defaultTag = 'default_dialog_queue_tag';typedef BSQueueDialogCondition = FutureOr<bool> Function(BuildContext context);
typedef BSQueueDialogShow = FutureOr<void> Function(BuildContext context);class BSQueueDialog {/// 是否應該顯示彈窗final BSQueueDialogCondition? shouldShow;/// 顯示彈窗final BSQueueDialogShow show;/// 彈窗優先級final int priority;const BSQueueDialog({this.shouldShow,required this.show,// 默認優先級為0,數值越大優先級越高this.priority = 0,});
}class DialogQueueManager {static final _instance = DialogQueueManager._internal();factory DialogQueueManager() => _instance;DialogQueueManager._internal();final _dialogQueue = <String, List<BSQueueDialog>>{};final _displayingDialog = <String, BSQueueDialog>{};Future<void> showQueueDialog<R>({required BuildContext context,BSQueueDialogCondition? shouldShow,required BSQueueDialogShow show,String tag = _defaultTag,int priority = 0,}) async {final dialog =BSQueueDialog(shouldShow: shouldShow, show: show, priority: priority);var queue = _dialogQueue[tag];if (queue == null) {queue = <BSQueueDialog>[];_dialogQueue[tag] = queue;}queue.add(dialog);// 按優先級排序隊列queue.sort((a, b) => b.priority.compareTo(a.priority));// 檢查是否有正在顯示的彈窗final displayingDialog = _displayingDialog[tag];if (displayingDialog == null) {_displayingDialog[tag] = dialog;await _showQueueDialog(context, tag);} else if (dialog.priority > displayingDialog.priority) {// 如果新彈窗優先級高,則關閉當前彈窗并顯示新彈窗Navigator.of(context).pop(); _displayingDialog.remove(tag);// 將當前彈窗重新添加到隊列中queue.add(displayingDialog);await _showQueueDialog(context, tag); // 顯示高優先級彈窗}}Future<void> _showQueueDialog<R>(BuildContext context, String tag) async {final queue = _dialogQueue[tag];if (queue == null || queue.isEmpty) {_dialogQueue.remove(tag);return;}final dialog = queue.removeAt(0);final shouldShow = await dialog.shouldShow?.call(context) ?? false;if (shouldShow) {_displayingDialog[tag] = dialog;await dialog.show(context);_displayingDialog.remove(tag);}return _showQueueDialog(context, tag);}
}

2. 獨立的 showQueueDialog 函數

Future<void> showQueueDialog<R>({required BuildContext context,BSQueueDialogCondition? shouldShow,required BSQueueDialogShow show,String tag = _defaultTag,int priority = 0, // 彈窗優先級
}) async {return DialogQueueManager().showQueueDialog(context: context,shouldShow: shouldShow,show: show,tag: tag,priority: priority,);
}

3. 使用示例

import 'package:flutter/material.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: 'Queue Dialog Example',home: MyHomePage(),);}
}class MyHomePage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Queue Dialog Example'),),body: Center(child: ElevatedButton(onPressed: () {showQueueDialog(context: context,shouldShow: (context) async {// 可以在這里添加條件邏輯return true;},show: (context) async {await showDialog(context: context,builder: (context) => AlertDialog(title: Text('Queue Dialog'),content: Text('This is a queued dialog with priority.'),actions: [TextButton(onPressed: () => Navigator.pop(context),child: Text('Close'),),],),);},priority: 1, // 設置彈窗優先級);},child: Text('Show Queue Dialog'),),),);}
}

四、代碼說明

  1. 單例模式:通過 DialogQueueManager 類實現單例模式,確保全局只有一個隊列管理實例。
  2. 線程安全:使用 synchronized 包中的 _lock 對象,確保對隊列的操作是線程安全的。
  3. 優先級排序:彈窗按優先級排序,高優先級的彈窗會優先顯示。
  4. 獨立函數:提供獨立的 showQueueDialog 函數,可在任何地方調用,不限于 StatefulWidget

五、總結

通過上述實現,我們構建了一個支持優先級的線程安全通用彈窗隊列管理系統。它不僅支持彈窗的按序顯示和條件判斷,還支持彈窗優先級,高優先級的彈窗會優先顯示。這種方式更加靈活,適用于更多場景,能夠有效簡化彈窗的管理邏輯,提高代碼的可維護性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77375.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77375.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77375.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鴻蒙NEXT開發剪貼板工具類(ArkTs)

import { pasteboard } from kit.BasicServicesKit; import { StrUtil } from ./StrUtil;/*** 剪貼板工具類* 需要權限&#xff1a;* ohos.permission.READ_PASTEBOARD // 允許應用讀取剪貼板。* author CSDN-鴻蒙布道師* since 2025/04/25*/ export class PasteboardUtil {…

FastAPI 零基礎入門指南:10 分鐘搭建高性能 API

一、為什么選擇 FastAPI&#xff1f; 想象一下&#xff0c;用 Python 寫 API 可以像搭積木一樣簡單&#xff0c;同時還能擁有媲美 Go 語言的性能&#xff0c;這個框架憑借三大核心優勢迅速風靡全球&#xff1a; 開發效率提升 3 倍&#xff1a;類型注解 自動文檔&#xff0c;…

【算法】BFS-解決FloodFill問題

目錄 FloodFill問題 圖像渲染 島嶼數量 島嶼的最大面積 被圍繞的區域 FloodFill問題 FloodFill就是洪水灌溉的意思&#xff0c;假設有下面的一塊田地&#xff0c;負數代表是凹地&#xff0c;正數代表是凸地&#xff0c;數字的大小表示凹或者凸的程度。現在下一場大雨&…

代碼隨想錄算法訓練營第三十七天|動態規劃part4

1049. 最后一塊石頭的重量 II 題目鏈接&#xff1a; 1049. 最后一塊石頭的重量 II - 力扣&#xff08;LeetCode&#xff09; 文章講解&#xff1a; 代碼隨想錄 思路&#xff1a; 理解為把石頭分成兩堆 使得兩堆的差值盡可能小 求這個最小值1 理解為往背包里裝物品 每個物品的…

(八)深入了解AVFoundation-采集:拍照功能的實現

引言 在上一篇文章中&#xff0c;我們初步完成了使用 AVFoundation 采集視頻數據的流程&#xff0c;掌握了 AVCaptureSession 的搭建與視頻流的預覽顯示。 本篇將繼續深入 AVFoundation&#xff0c;聚焦于靜態圖片采集的實現。通過 AVCapturePhotoOutput&#xff0c;我們可以…

git tag使用場景和實踐

背景 每次上線一個迭代&#xff0c;為了區分本次代碼的分支是哪個迭代的commit&#xff0c;可以給分支打上tag&#xff0c;這樣利于追蹤分支所屬迭代&#xff0c;如果devops沒有自動給分支打tag&#xff0c;需要自己來打 操作 1.查看當前tag git tag2.給分支打tag git tag…

從零開始掌握Linux數據流:管道與重定向完全指南

全文目錄 1 知識背景與核心概念1.1 操作系統的輸入輸出模型1.2 Shell 的中間人角色 2 重定向技術深度解析2.1 輸出重定向2.1.1 覆蓋寫2.1.2 追加寫2.1.3 錯誤重定向2.1.4 同時重定向 stdout 和 stderr 2.2 輸入重定向2.2.1 文件作為輸入源2.2.2 Here Document&#xff08;多行輸…

aws(學習筆記第三十九課) iot-core

文章目錄 aws(學習筆記第三十九課) iotcore(Internet Of Thing)學習內容:1. 整體架構1.1 代碼鏈接1.2 整體架構(概要)1.3 整體架構(詳細 )2. 代碼解析2.1 創建`IOT thing`2.2 創建`AWS IOT certificate`證書2.2.1 創建`lambda`需要的`role`2.2.2 創建`lambda`2.2.3 `lambd…

國家新政鼓勵游戲出海,全球化安全威脅如何解

本文作者&#xff1a;騰訊宙斯盾DDoS防護團隊 01 政策紅利釋放&#xff1a;游戲出海升級為“國家戰略工程” 01 4月21日&#xff0c;國務院新聞辦公室發布《加快推進服務業擴大開放綜合試點工作方案》&#xff0c;釋放了一個信號&#xff1a;首次將“游戲出海”列為戰略級工程&…

MobX 在 React 中的使用:狀態管理的新選擇

&#x1f90d; 前端開發工程師、技術日更博主、已過CET6 &#x1f368; 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 &#x1f560; 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》、《前端求職突破計劃》 &#x1f35a; 藍橋云課簽約作者、…

Idea 配置 Git

1、下載Git 下載地址&#xff1a; Git - Downloading Package 2、win 打開 git bash &#xff0c;配置郵箱和用戶名 //配置郵箱 git config --global user.email "710419844qq.com" //配置全局用戶名 git config --global user.name "smelodys" 3、ide…

Vue3 + OpenLayers 開發教程 (四) 樣式配置與性能優化

1. 地圖樣式基礎概念 1.1 什么是地圖樣式&#xff1f; 地圖樣式是決定地圖要素&#xff08;點、線、面&#xff09;如何顯示的重要配置。在 OpenLayers 中&#xff0c;樣式主要包含以下幾個核心組件&#xff1a; Fill&#xff08;填充&#xff09;&#xff1a;控制面狀要素的…

【Nacos-安全與限流機制健全06 】

文章目錄 Nacos安全機制介紹Nacos代碼實現Nacos限流機制Nacos限流的代碼實現 Nacos安全機制介紹 一、Nacos安全控制機制 Nacos 提供了多種安全控制機制&#xff0c;以保證服務和配置的訪問安全&#xff1a; 身份驗證 (Authentication) Nacos 支持用戶身份驗證來防止未授權的訪…

自建開源遠程協助服務RustDesk —— 筑夢之路

開源項目 # 服務端https://github.com/rustdesk/rustdesk-server.git# 客戶端https://github.com/rustdesk/rustdesk.git 搭建服務端 需要使用的端口、協議 hbbs - RustDesk ID 注冊服務器 hbbr - RustDesk 中繼服務器默認情況下&#xff0c;hbbs 監聽 21115(tcp) , 21…

Jmeter中同步定時器使用注意點

1.設置數量不可大于總線程數量&#xff0c;不然會一直等待 2.設置數量必須與總線程數量成整數倍數&#xff0c;不然還是要一直等。 3.當配置的數量小于線程數時&#xff0c;最好把循環打開&#xff0c;避免最后一次未準備好的線程數量達不到并發數。

作為高速通道光纖傳輸模式怎么理解以及到底有哪些?

光纖的傳輸模式主要取決于光纖的結構(如纖芯直徑和折射率分布),不同模式對應光波在光纖中傳播的不同路徑和電磁場分布。以下是光纖傳輸模式的主要分類及特點: 1. 單模光纖(Single-Mode Fiber, SMF) 核心特點: 纖芯直徑極小(通常為 8-10微米),僅允許光以單一模式(…

小程序Npm package entry file not found?

修改依賴包的入口文件 看是不是cjs&#xff0c;小程序不支持cjs

Android HAL HIDL

1 Android HAL HIDL 1.1 Android中查看有哪些HIDL HAL HIDL是Treble Interface的一部分。 adb root adb shell # lshal 1.2 Android打印C調用棧 #include <utils/CallStack.h> 在需要打印的地方加如下的定義。 android::CallStack stack("oem"); logcat | g…

【AI 加持下的 Python 編程實戰 2_11】DIY 拓展:從掃雷小游戲開發再探問題分解與 AI 代碼調試能力(下)

&#xff08;接 上篇&#xff09; 5 復盤與 Copilot 的交互過程 前面兩篇文章分別涵蓋了掃雷游戲的問題分解和代碼實現過程&#xff0c;不知道各位是否會有代碼一氣呵成的錯覺&#xff1f;實際上&#xff0c;為了達到最終效果&#xff08;如下所示&#xff09;&#xff0c;我…

游戲狀態管理:用Pygame實現場景切換與暫停功能

游戲狀態管理:用Pygame實現場景切換與暫停功能 在開發游戲時,管理游戲的不同狀態(如主菜單、游戲進行中、暫停等)是非常重要的。這不僅有助于提升玩家的游戲體驗,還能使代碼結構更加清晰。本文將通過一個簡單的示例,展示如何使用Pygame庫來實現游戲中的場景切換和暫停功…