应用弹窗优先级

背景

由于活动业务越来越多,积累的弹窗越来越多和杂乱,出现如下弹窗交互问题:

  • 弹窗无限重叠,影响操作

  • 弹出顺序无优先级,重要弹窗被隐藏

原因相信大家都一样,产品是一次次迭代的,也可能是不同人开发的,两个毫不相关的业务,弹窗时机也没有任何关联,重不重叠我怎么控制呀

首先来分析一下我们的预期

经过总结后,我想要的弹窗效果如下:

  • 短时间内弹出多个弹窗情况下,一次只能显示一个,其他的都加到队列里等待;
  • 下一个弹窗弹出的时机,是在当前弹窗关闭之后;
  • 队列中的弹窗不是无限等待的,超时后不能显示(出队列的时间-入队列的时间,超时时间可设置)
  • 队列中的弹窗显示按照优先级排列(可设置优先级)

当然,除了满足上面的业务条件外,对当前代码的侵入性,代码可靠性也同样重要,不然改了一顿之后上线都是bug,那这个就得不偿失了;

设计阶段

为了后续开发清晰,我总结了一个流程图

设计DialogManager类:

定义需要的结构

object DialogShowManager {

    //弹窗等待队列
    private val mQueueList by lazy { LinkedList<ConfigDialogFragment>() }

    //优先级计算
    private var mComparator = Comparator<ConfigDialogFragment> { e1, e2 -> e2.config.priority - e1.config.priority}

    //当前正在显示的dialog
    private var mCurrentDialog:ConfigDialogFragment? = null

//....

}

定义显示dialog的入口方法:

fun addDialog(dialog: DialogFragment, fragmentManager: FragmentManager?, flags: Int, config: DialogShowConfig) {
        log("addDialog::${dialog.javaClass.simpleName}")
        val configDialog = ConfigDialogFragment(dialog, fragmentManager,flags, config.apply { joinTime = System.currentTimeMillis()})
        if (mCurrentDialog == null) {
            showDialogInternal(configDialog)
            return
        }
        log("addDialog add to queue::${dialog.javaClass.simpleName}")
        mQueueList.add(configDialog)
        Collections.sort(mQueueList, mComparator)
    }

显示dialog,如果当前没有正在显示的弹窗,则直接进入显示弹窗;如果有,则直接加入队列;

显示弹窗内部逻辑:

private fun showDialogInternal(dialogFragment: ConfigDialogFragment) {
        log("showDialogInternal::${dialogFragment.dialog.javaClass.simpleName}")
        mCurrentDialog = dialogFragment
        mCurrentDialog?.dialog?.lifecycle?.addObserver(mDialogObserver)
        Navigator.showDialog(dialogFragment.dialog, dialogFragment.fragmentManager, dialogFragment.flags)
    }

注意,显示之前,为当前弹窗添加了lifecycleObserver,用来监听弹窗的生命周期;

Navigator.showDialog为内部封装显示dialogFragment的方法;

当前弹窗的生命周期监听:

private val mDialogObserver = object: LifecycleObserver {

        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        fun onCreate(owner: LifecycleOwner) {
            log("mDialogObserver::onCreate")
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        fun onDestroy(owner: LifecycleOwner) {
            log("mDialogObserver::onDestroy")
            mCurrentDialog?.dialog?.lifecycle?.removeObserver(this)
            mCurrentDialog = null
            showNextDialog()
        }
    }

 因为注册了lifecycleObserver,所以在这里可以监听到弹窗的开启和关闭,在关闭时清空当前弹窗并执行显示下一个弹窗的逻辑

显示下一个弹窗:

private fun showNextDialog() {
        log("showNextDialog")
        while (true) {
            val dialog = mQueueList.poll() ?: return
            log("showNextDialog::isTimeout::${dialog.isTimeout()},::${dialog.dialog.javaClass.simpleName}")
            if (!dialog.isTimeout()) {
                showDialogInternal(dialog)
                return
            }
            continue
        }

    }

 找到队列里下一个未超时的弹窗,并进入执行显示逻辑

 这样,业务里弹窗时,只需要调用DialogShowManager.addDialog即可,传入需要显示的dialog和优先级配置等;

此方案的优点是侵入性小,没有复杂的判断逻辑,健壮性好,只使用少量的代码即实现了预想的方案;

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据需求,以下是关于手环系统优先级的测试用例: 1. 测试用例名称:来电优先级 描述:验证来电在手环系统中的优先级是否正确 步骤: 1. 模拟来电事件 2. 检查手环系统是否正确显示来电 预期结果:来电应具有较高的优先级,能够及时显示并提醒用户 2. 测试用例名称:闹钟优先级 描述:验证闹钟在手环系统中的优先级是否正确 步骤: 1. 设置一个闹钟并等待触发 2. 检查手环系统是否正确显示闹钟 预期结果:闹钟应具有较高的优先级,能够及时显示并提醒用户 3. 测试用例名称:日程(事件)提醒优先级 描述:验证日程(事件)提醒在手环系统中的优先级是否正确 步骤: 1. 设置一个日程事件并等待触发 2. 检查手环系统是否正确显示日程(事件)提醒 预期结果:日程(事件)提醒应具有较高的优先级,能够及时显示并提醒用户 4. 测试用例名称:查找我的手表优先级 描述:验证查找我的手表在手环系统中的优先级是否正确 步骤: 1. 触发查找我的手表功能 2. 检查手环系统是否正确显示查找我的手表 预期结果:查找我的手表应具有较高的优先级,能够立即显示并引起用户的注意 5. 测试用例名称:定时器优先级 描述:验证定时器在手环系统中的优先级是否正确 步骤: 1. 设置一个定时器并等待触发 2. 检查手环系统是否正确显示定时器 预期结果:定时器应具有较高的优先级,能够及时显示并提醒用户 6. 测试用例名称:跌倒检测优先级 描述:验证跌倒检测在手环系统中的优先级是否正确 步骤: 1. 模拟跌倒事件 2. 检查手环系统是否正确显示跌倒检测 预期结果:跌倒检测应具有较高的优先级,能够及时显示并提醒用户 7. 测试用例名称:其他系统优先级 描述:验证其他系统(如系统更新、低电量等)在手环系统中的优先级是否正确 步骤: 1. 触发其他系统事件(如系统更新、低电量等) 2. 检查手环系统是否正确显示相应的 预期结果:其他系统应具有适当的优先级,能够及时显示并提醒用户 以上是关于手环系统优先级的测试用例,根据需要可以进一步细化和补充。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龍林1102

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值