【Android】【設計模式】抽象工廠模式改造彈窗組件必知必會

寫一個 Android 版本的抽象工廠彈窗 + Manager 管理器,使用 DialogFragment 實現,這樣能更貼近真實的開發場景。


結構設計

  1. 抽象產品BaseDialogFragment(繼承 DialogFragment
  2. 具體產品LoginDialogFragment, UpdateDialogFragment
  3. 抽象工廠DialogFactory
  4. 具體工廠LoginDialogFactory, UpdateDialogFactory
  5. 彈窗管理器DialogManager(統一展示 / 關閉彈窗)

代碼實現

抽象產品

import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;public abstract class BaseDialogFragment extends DialogFragment {@NonNull@Overridepublic abstract Dialog onCreateDialog(@Nullable Bundle savedInstanceState);public void dismissDialog() {if (getDialog() != null && getDialog().isShowing()) {dismiss();}}
}

具體產品

import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;public class LoginDialogFragment extends BaseDialogFragment {@NonNull@Overridepublic Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {return new AlertDialog.Builder(requireContext()).setTitle("登錄").setMessage("請輸入賬號密碼").setPositiveButton("確定", (dialog, which) -> {// 登錄邏輯}).setNegativeButton("取消", null).create();}
}
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;public class UpdateDialogFragment extends BaseDialogFragment {@NonNull@Overridepublic Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {return new AlertDialog.Builder(requireContext()).setTitle("更新提示").setMessage("檢測到新版本,是否更新?").setPositiveButton("更新", (dialog, which) -> {// 更新邏輯}).setNegativeButton("稍后", null).create();}
}

抽象工廠

public interface DialogFactory {BaseDialogFragment createDialog();
}

具體工廠

public class LoginDialogFactory implements DialogFactory {@Overridepublic BaseDialogFragment createDialog() {return new LoginDialogFragment();}
}
public class UpdateDialogFactory implements DialogFactory {@Overridepublic BaseDialogFragment createDialog() {return new UpdateDialogFragment();}
}

彈窗管理器

import androidx.fragment.app.FragmentManager;
import java.util.HashMap;
import java.util.Map;public class DialogManager {private static final Map<String, BaseDialogFragment> dialogCache = new HashMap<>();public static void showDialog(String key, DialogFactory factory, FragmentManager fragmentManager) {if (!dialogCache.containsKey(key)) {dialogCache.put(key, factory.createDialog());}BaseDialogFragment dialog = dialogCache.get(key);if (dialog != null && !dialog.isAdded()) {dialog.show(fragmentManager, key);}}public static void dismissDialog(String key) {BaseDialogFragment dialog = dialogCache.get(key);if (dialog != null) {dialog.dismissDialog();dialogCache.remove(key);}}
}

使用示例 (Activity 中調用)

public class MainActivity extends AppCompatActivity {@Overrideprotected void onResume() {super.onResume();// 顯示登錄彈窗DialogManager.showDialog("login", new LoginDialogFactory(), getSupportFragmentManager());// 顯示更新彈窗DialogManager.showDialog("update", new UpdateDialogFactory(), getSupportFragmentManager());// 關閉登錄彈窗DialogManager.dismissDialog("login");}
}

? 優點:

  • 擴展性強:新增一個彈窗,只需要新增 DialogFragment + FactoryDialogManager 無需改動
  • 全局管理:可以統一控制彈窗的緩存、復用、顯示/關閉邏輯
  • 線程安全:使用 FragmentManager 管理生命周期,避免內存泄漏

再加一個 全局策略(比如保證同一時間只顯示一個彈窗,后來的會自動關閉之前的)

DialogManager 里加一個 全局策略:同一時間只允許顯示一個彈窗。這樣新的彈窗顯示時,會自動關閉之前的。


改造后的 DialogManager

import androidx.fragment.app.FragmentManager;
import java.util.HashMap;
import java.util.Map;public class DialogManager {private static final Map<String, BaseDialogFragment> dialogCache = new HashMap<>();private static String currentDialogKey = null; // 當前正在顯示的彈窗 keypublic static void showDialog(String key, DialogFactory factory, FragmentManager fragmentManager) {// 如果有正在顯示的彈窗,先關閉if (currentDialogKey != null && dialogCache.containsKey(currentDialogKey)) {dismissDialog(currentDialogKey);}// 創建或獲取彈窗if (!dialogCache.containsKey(key)) {dialogCache.put(key, factory.createDialog());}BaseDialogFragment dialog = dialogCache.get(key);// 顯示彈窗if (dialog != null && !dialog.isAdded()) {dialog.show(fragmentManager, key);currentDialogKey = key;}}public static void dismissDialog(String key) {BaseDialogFragment dialog = dialogCache.get(key);if (dialog != null) {dialog.dismissDialog();dialogCache.remove(key);if (key.equals(currentDialogKey)) {currentDialogKey = null;}}}public static void dismissCurrentDialog() {if (currentDialogKey != null) {dismissDialog(currentDialogKey);}}public static boolean isDialogShowing() {return currentDialogKey != null;}
}

使用示例

public class MainActivity extends AppCompatActivity {@Overrideprotected void onResume() {super.onResume();// 顯示登錄彈窗DialogManager.showDialog("login", new LoginDialogFactory(), getSupportFragmentManager());// 這里再顯示更新彈窗時,會自動關閉上一個(login)DialogManager.showDialog("update", new UpdateDialogFactory(), getSupportFragmentManager());// 關閉當前正在顯示的彈窗(update)DialogManager.dismissCurrentDialog();}
}

? 這樣就具備了:

  1. 抽象工廠擴展性:新增彈窗不用改管理器。
  2. 緩存 & 復用:避免重復創建相同彈窗。
  3. 全局策略:同一時間只顯示一個彈窗。
  4. 可選擴展:還能加優先級隊列(比如:強制更新彈窗 > 登錄彈窗 > 普通提示彈窗)。

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

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

相關文章

Win64OpenSSL-3_5_2.exe【安裝步驟】

官網下載 注意&#xff1a;科學上網&#xff0c;可以加速下載速度&#xff01; Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions 下載后得到&#xff1a;Win64OpenSSL-3_5_2.exe 雙擊安裝 修改安裝路徑&#xff1a; 默認就選擇第一個。 重要提醒?…

華為云云原生架構賦能:大騰智能加速業務創新步伐

巨大的渦輪、細小的螺絲&#xff0c;一臺航天飛機發動機的三維模型呈現在屏幕上&#xff0c;遠程同事同步協作&#xff0c;一臺復雜設備在工程師高效的協同中不斷完善。深圳市大騰信息技術有限公司&#xff0c;正是這場工業變革的推動者之一。大騰智能以“云原生工業”的融合為…

基于https+域名的Frp內網穿透教程(Linux+Nginx反向代理)

系列文章目錄 基于http公網ip的Frp內網穿透教程(win server) 基于http域名的Frp內網穿透教程(win serverIIS反向代理) 基于http公網ip的Frp內網穿透教程(Linux) 基于https域名的Frp內網穿透教程(LinuxNginx反向代理) 目錄 系列文章目錄 前言 一、Frp是什么&#xff1f; 1. …

裸機程序(1)

一、裸機裸機是一個在計算機硬件與軟件開發領域高頻出現的概念&#xff0c;核心定義是 “未安裝操作系統&#xff08;OS&#xff09;&#xff0c;僅包含硬件本身&#xff08;或僅運行最底層硬件驅動 / 控制程序&#xff09;的設備”。在電腦中&#xff0c;裸機會映射代碼到cpu&…

95%企業AI失敗?揭秘LangGraph+OceanBase融合數據層如何破局!?

本文較長&#xff0c;建議點贊收藏&#xff0c;以免遺失。更多AI大模型應用開發學習視頻及資料&#xff0c;盡在聚客AI學院。不知道你們有沒有遇到過&#xff0c;在我們一些實際落地的AI項目中&#xff0c;雖然前期“Demo 很驚艷&#xff0c;但上線后卻無人問津”。你們有沒有想…

樹莓集團產教融合:數字學院踐行職業教育“實體化運營”要求

在職業教育改革不斷深化的背景下&#xff0c;“實體化運營” 成為推動職業教育高質量發展的重要方向。樹莓集團積極響應這一要求&#xff0c;以產教融合為核心&#xff0c;打造數字學院&#xff0c;切實踐行職業教育 “實體化運營”&#xff0c;為培養高素質數字領域專業人才探…

ELK 統一日志分析系統部署與實踐指南(上)

#作者&#xff1a;張桐瑞 文章目錄1 ELK 技術棧概述1.1ELK 核心組件詳解1.2 ELK 工作流程2 ELK部署2.1 環境描述2.1.7 配置es集群下篇&#xff1a;《ELK 統一日志分析系統部署與實踐指南&#xff08;下&#xff09;》 鏈接: [https://blog.csdn.net/qq_40477248/article/detail…

上位機知識篇---poweshellcmd

要理解 PowerShell 和 CMD 的區別&#xff0c;我們可以先打個通俗的比方&#xff1a;CMD 像老式功能機&#xff0c;只能干打電話、發短信這些 “基礎活”&#xff1b;而 PowerShell 像智能手機&#xff0c;不僅能做基礎操作&#xff0c;還能裝 APP、玩復雜功能&#xff0c;甚至…

利用 Python 繪制環形熱力圖

暑假伊始&#xff0c;Coldrain 參加了學校舉辦的數模集訓&#xff0c;集訓的過程中&#xff0c;遇到了需要展示 59 個特征與 15 個指標之間的相關性的情況&#xff0c;在常用的圖表不大合適的情況下&#xff0c;學到了一些厲害的圖表&#xff0c;但是似乎千篇一律都是用 R 語言…

【序列晉升】27 Spring Cloud Sleuth給分布式系統裝上透視鏡

Spring Cloud Sleuth作為微服務架構中的核心監控組件&#xff0c;通過輕量級的無侵入式跟蹤機制&#xff0c;解決了分布式系統中請求路徑復雜、問題定位困難的痛點。它自動為每個服務請求創建唯一的Trace ID&#xff0c;并為每個服務間調用生成Span ID&#xff0c;形成完整的調…

Linux(2)|入門的開始:Linux基本指令(2)

一、基本指令介紹 回顧上篇博客Linux(1)|入門的開始&#xff1a;Linux基本指令-CSDN博客&#xff0c;我們已經學習了mkdir目錄的創建&#xff0c;touch普通文件的創建&#xff0c;光有創建肯定是不行的&#xff0c;接下來就介紹我們的刪除指令 1、rmdir指令&&rm指令 …

sv中forever如何結束

在 SystemVerilog 中&#xff0c;forever 循環本身無法自我結束。它的設計初衷就是創建一個永不終止的循環。 因此&#xff0c;要結束一個 forever 循環&#xff0c;必須從外部強制中斷它。主要有以下兩種方法&#xff1a;1. 使用 disable 語句&#xff08;最常用和推薦的方法&…

關于熵減 - 從法拉第圓盤到SEG

我們清楚的知道法拉第圓盤發電機的原理。當導線切割磁感線的時候&#xff0c;會產生電流&#xff0c;當然電流產生需要的是電動勢&#xff0c;也就是&#xff0c;這里寫 不寫 &#xff0c;避免和電場強度混淆。根據上面的分析&#xff0c;我們知道磁場強度特斯拉 的單位&#x…

【機器學習】實戰:市場增長點分析挖掘項目

在電商行業激烈競爭的背景下&#xff0c;精準挖掘市場增長點是企業保持競爭力的關鍵。本文基于拜耳官方旗艦店驅蟲劑市場分析項目&#xff0c;先對原文核心內容進行梳理與解讀&#xff0c;再續寫關鍵的競爭分析模塊&#xff0c;形成完整的市場增長點挖掘閉環&#xff0c;為企業…

【Day 18】21.合并兩個有序鏈表 2.兩數相加

文章目錄21.合并兩個有序鏈表題目&#xff1a;思路&#xff1a;迭代代碼實現&#xff08;Go&#xff09;&#xff1a;2.兩數相加題目&#xff1a;思路&#xff1a;代碼實現&#xff08;Go&#xff09;&#xff1a;21.合并兩個有序鏈表 題目&#xff1a; 將兩個升序鏈表合并為…

Vue 3 WebSocket通信方案:從原理到實踐

Vue 3 WebSocket通信方案&#xff1a;從原理到實踐 在現代Web應用開發中&#xff0c;實時通信已成為許多應用的核心需求。從即時聊天到實時數據更新&#xff0c;用戶對應用響應速度的期望越來越高。本文將深入剖析一個Vue 3環境下的WebSocket通信方案&#xff0c;包括基礎封裝與…

Windows 電源管理和 Shutdown 命令詳解

一、Windows 電源管理概述 Windows 操作系統通過其內置的電源管理框架&#xff0c;為用戶提供了多種電源狀態和配置選項&#xff0c;以在性能、能耗和數據安全之間找到最佳平衡點。以下是 Windows 系統中常見的電源狀態及其特點&#xff1a; 1. 睡眠&#xff08;Sleep&#xff…

Selenium WebUI 自動化“避坑”指南——從常用 API 到 10 大高頻問題

目錄 一、為什么 90% 的 UI 自動化腳本活不過 3 個月&#xff1f; 二、Selenium必會 API 速查 三、實踐 四、10 大高頻異常“癥狀 → 病因 → 處方” 五、可復用的工具函數 六、面試高頻追問&#xff08;附標準答案&#xff09; 一、為什么 90% 的 UI 自動化腳本活不過 …

【微信小程序】微信小程序基于雙token的API請求封裝與無感刷新實現方案

文章目錄前言一、設計思路二、執行流程三、核心模塊3.1 全局配置3.2 request封裝3.2.1 request方法配置參數3.2.2 請求預處理3.2.3 核心請求流程3.3 刷新accessToken3.4 輔助方法四、api封裝示例總結前言 現代前后端分離的模式中&#xff0c;一般都是采用token的方式實現API的…

基于單片機醉酒駕駛檢測系統/酒精檢測/防疲勞駕駛設計

傳送門 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目速選一覽表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目功能速覽 概述 該設計基于單片機開發&#xff0c;旨在通過實時檢測駕駛員酒精濃度&#xff0c;預防酒后駕駛行為…