前言
在Android圈里关于弹窗的开源框架还是挺多的,但是大多数扩展都是针对于样式,像是一种类型的弹窗开发者传入不同的参数就能在UI效果上显示不同的特效,这样的扩展的确是十分方便但在我们具体工作业务开发中,UI对弹窗样式的追求上
就显得有些鸡肋,基本上业务场景每种类型的弹窗界面效果都大不相同做不到真正意义上的界面统一
这里对于将要介绍的方案 着重的不在于UI效果 而在于 弹窗的业务逻辑
思想理念
得益于markzhai的任务流概念将App初始化的流程抽象为flow、wave和task 三个阶段类别的想法
我整理了弹窗相关的一些类别 (ps:这里的弹窗不再是Dialog通常的概念)
public enum PopType {
DIALOG,
WEBVIEW,
WIDGET,
POUPOWINDOW,
TOAST,
SNACKBAR,
OTHERS
}
我也尝试着将这些繁杂的弹窗统一抽象为一体 也就是本框架中的核心成员之一 —— PopLayerView
它是一个弹窗view但又不继承于View 并且具备原生弹窗show,hide等基本功能
它可以是上面列出的弹窗的任何一种 只需要传入你的具体弹窗策略
框架产于需求终于需求 需求文档里 可能需要你将弹窗延迟固定的时间并消失 一些活动弹窗需要你在具体的时间段失效 又或者是当运营下发多个活动窗口时 该如何满足他们需求的管理这些弹窗
面对上述的这些问题
弹窗就不限于弹窗本身了,它必须具备装配各种业务相匹配的能力
1.时间范围管理 2.显示弹窗次数管理 3.优先级设置 4.显示时间配置
内部维护了 PopLayerController 装配弹窗业务功能的成员来满足这些场景
成员 PopManager 维护了对应的弹窗优先级队列 保证弹窗流程正常进行
综上暂时满足目前的需求,希望这样的思想理念能得到您的赞同
具体使用
具体使用 您可以去 Github:github.com/MrCodeSnipe… 上浏览希望对您有所帮助
//add this to your repositories
maven { url 'https://www.jitpack.io' }
//add this to your dependencies
implementation 'com.github.MrCodeSniper:PopLayer:2.0.0'
关于弹窗管理
这里 我将每个弹窗对象 当成一个弹窗实体 在框架里称为 Popi
它是一个描述窗口的最小不可分割实体 具备所有描述弹窗的属性且可以按照需求扩展
在使用时 只需按照您的需求 装配对应的业务需求即可
Popi mUpgradePopi1 = new Popi.Builder()
.setmPopId(4)//弹窗的唯一标识 当id发生改变 视为新的弹窗
.setmPriority(2)//优先级这里不具体划分对应的范围 值越小优先级越高
.setmCancelType(TRIGGER_CANCEL)//弹窗消失的类型分为 TRIGGER_CANCEL(触摸消失) COUNTDOWN_CANCEL (延时消失)
.setMaxShowTimeLength(5)//最长显示时间(S)
.setMaxShowCount(5)//最大显示次数
.setmBeginDate(1548858028)//开始时间 2019-01-30 22:20:28
.setmEndDate(1548944428)//结束时间 2019-01-31 22:20:28
.setmPopLayerView(mLayerView1)//弹窗View
.build();
之前说过传入具体弹窗策略 创建对应的弹窗
即下文中的传入dialog弹窗的策略 拿到之前统一的View对象交由Popi管理即可
//Dialog形式
PopLayerView mLayerView = new PopLayerView(this,R.layout.common_dialog_upgrade_app);
//透明Webview形式
PopLayerView mLayerView = new PopLayerView(this,LayerConfig.redPocketScheme);
如何实现弹窗优先级的业务逻辑
之前说到 成员 PopManager 维护了对应的弹窗优先级队列 保证弹窗流程正常进行,最后的显示和隐藏也是在其操作之后
首先Popi实体实现了Comparable接口 使其具备通过优先级比较大小的能力
其次也就是内部的优先级队列 每添加删除一个元素都会进行堆排序对队列进行优先级调整
private PriorityQueue queue;
当弹窗实体Popi入队中 会先通过判断其Id是否重复 来判断是否将其入队
在显示时根据传入的Popi对应的属性依次判断其是否满足
1.在限定的活动时间内
2.通过SP保存相应弹窗的显示次数 key为Popi加上其唯一的ID 判断显示次数是否超出范围
3.如果取消类型为延迟取消 增加DelayDimiss
若流程无法走出的弹窗实体会被移出队列
具体的使用也非常简单
//纳入弹窗管理
PopManager.getInstance().pushToQueue(mUpgradePopi);
//开始显示弹窗
PopManager.getInstance().showNextPopi();
效果预览
框架目前的缺陷
目前还没有好的方法来监听原生的控件消失的回调
类似dialog 点击圈外时 是不走我们的消失逻辑的
需要加上监听 但这使得内部逻辑有些紊乱
目前的解决办法是 统一弹窗的 触摸机制 分为实体和外围区域 将其纳入我们的管理范围内
随着V2的发布 触摸机制 已经有默认不同扩展的实现 基本上实现统一
关于项目
V1方案
版本号
LOG
进度更新
V1.0.0
项目开源,完成弹窗管理与Dialog形式扩展
Dialog策略扩展完成
V1.0.1
修复Dialog策略无法获取dialog实体bug
Dialog策略优化
V1.0.2
修复activity摧毁造成的弹窗异常 bug
Dialog策略优化
V1.0.3
优化了弹窗的使用更加方便快捷
框架使用优化
V2方案
版本号
LOG
进度更新
V2.0.0
正式加入透明Webview弹窗策略扩展
透明Webview策略扩展完成
未来的计划
基于透明的Webview的扩展已经完成 各位看官可以去
其他类型的弹窗也会陆续更新 希望能提供给大家一个较为全面的应对业务需求的弹窗管理框架
作者介绍
Hello 我叫lalala,如果您喜欢我的文章,可以去我的Github给个Star我就很开心啦!
--End