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

【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.xdnf.cn/news/1448983.html

相关文章:

  • Wan2.2AllInOne - Wan2.2极速视频生成模型,4步极速生成 ComfyUI工作流 一键整合包下载
  • 深度学习篇---模型组成部分
  • http和https区别是什么
  • Spring Boot 2.7 中资源销毁的先后顺序
  • mysqldump导出远程的数据库表(在java代码中实现)
  • VUE的模版渲染过程
  • FFMPEG H264
  • OpenLayers常用控件 -- 章节一:地图缩放控件详解教程
  • 如何通过level2千档盘口分析挂单意图
  • JavaScript的输出语句
  • 三阶Bezier曲线,已知曲线上一点到曲线起点的距离为L,计算这个点的参数u的方法
  • 专题四_前缀和_一维前缀和
  • 【OC】属性关键字
  • vtk资料整理
  • Linux arm64 PTE contiguous bit
  • linux可以直接用指针操作物理地址吗?
  • torch学习 自用
  • python类的内置属性
  • AI重塑SaaS:从被动工具到智能角色的技术演进路径
  • 【面试题】OOV(未登录词)问题如何解决?
  • Leetcode_202.快乐数_三种方法解决(普通方法解决,哈希表解决,循环链表的性质解决_快慢指针)
  • 简述:普瑞时空数据建库软件(国土变更建库)之一(变更预检查部分规则)
  • PyTorch 中训练语言模型过程
  • 利用 Java 爬虫获取淘宝商品详情 API 接口
  • 嵌入式学习day41-硬件(2)
  • ansible总结2
  • 代码随想录算法训练营第一天 | 704.二分查找 27. 移除元素 977.有序数组的平方
  • python中`__annotations__` 和 `inspect` 模块区别??
  • 两个子进程之间使用命名pipe
  • 从月薪5K到年薪60W!API自动化测试如何让你突破职业瓶颈