前言

在 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. 显示时间配置

Poplayer 内部维护了 PopLayerController 装配弹窗业务功能的成员来满足这些场景

成员 PopManager 维护了对应的弹窗优先级队列 保证弹窗流程正常进行

综上暂时满足目前的需求, 希望这样的思想理念能得到您的赞同

具体使用

关于 Poplayer 的具体使用 您可以去 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:1.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 弹窗的策略 拿到之前统一的 PopLayerView 对象交由 Popi 管理即可

PopLayerView mLayerView=new PopLayerView(this);
// 第一个参数为 dialog 的布局 第二个参数为 dialog 的主题
mLayerView.setiLayerStrategy(new DialogLayerStrategyImpl(R.layout.common_dialog_upgrade_app,R.style.FullTransDialog));
复制代码

如何实现弹窗优先级的业务逻辑

之前说到 成员 PopManager 维护了对应的弹窗优先级队列 保证弹窗流程正常进行,最后的显示和隐藏也是在其操作之后

首先 Popi 实体实现了 Comparable 接口 使其具备通过优先级比较大小的能力

其次也就是内部的优先级队列 每添加删除一个元素都会进行堆排序对队列进行优先级调整

private  PriorityQueue<Popi> queue;
复制代码

当弹窗实体 Popi 入队中 会先通过判断其 Id 是否重复 来判断是否将其入队

在显示时根据传入的 Popi 对应的属性依次判断其是否满足

1. 在限定的活动时间内

2. 通过 SP 保存相应弹窗的显示次数 key 为 Popi 加上其唯一的 ID 判断显示次数是否超出范围

3. 如果取消类型为延迟取消 增加 DelayDimiss

若流程无法走出的弹窗实体会被移出队列

具体的使用也非常简单

// 纳入弹窗管理
PopManager.getInstance().pushToQueue(mUpgradePopi);
// 开始显示弹窗
PopManager.getInstance().showNextPopi();
复制代码

效果预览

框架目前的缺陷

目前还没有好的方法来监听原生的控件消失的回调

类似 dialog 点击圈外时 是不走我们的 Poplayer 消失逻辑的

需要加上监听 但这使得 Poplayer 内部的逻辑有些紊乱

目前的解决办法是 统一弹窗的 触摸机制 分为实体和外围区域 将其纳入我们的管理范围内

未来的计划

很抱歉的是 目前的框架只涉及到了 Dialog 相关的业务逻辑

类似手淘在其云溪社区提供的方案基于透明的 Webview 也在筹备之中, 会从全方面统筹 webview

其他类型的弹窗也会陆续更新 希望能提供给大家一个较为全面的应对业务需求的弹窗管理框架


Hello 我叫 lalala, 如果您喜欢我的文章, 可以去我的 Github 给个 Star 我就很开心啦!

Github:github.com/MrCodeSnipe…

Thanks To 手淘在其云溪社区提供的方案提供的封面图片

--End

  • Android

    开放手机联盟(一个由 30 多家科技公司和手机公司组成的团体)已开发出 Android,Android 是第一个完整、开放、免费的手机平台。

    293 引用
感谢    赞同    分享    收藏    关注    反对    举报    ...