注册

Dialog 按照顺序弹窗

背景: 产品需求,在同一个页面弹窗需要按照顺序

实现: 利用PriorityQueue现实,支持相同优先级,按插入时间排序,目前仅支持Activity,不支持Fragment

代码: DialogPriorityUtil 实现优先级弹窗

/**
* ClassName: DialogPriorityUtil
* Description: show dialog by priority
* author Neo
* since 2021-09-15 20:15
* version 1.0
*/
object DialogPriorityUtil : LifecycleObserver {

private val dialogPriorityQueue = PriorityQueue<PriorityDialogWrapper>()

private var hasDialogShowing = false

@MainThread
fun bindLifeCycle(appCompatActivity: AppCompatActivity) {
appCompatActivity.lifecycle.addObserver(this)
}

@MainThread
fun showDialogByPriority(dialogWrapper: PriorityDialogWrapper? = null) {
if (dialogWrapper != null) {
dialogPriorityQueue.offer(dialogWrapper)
}
if (hasDialogShowing) return
val maxPriority: PriorityDialogWrapper = dialogPriorityQueue.poll() ?: return
if (!maxPriority.isShowing()) {
hasDialogShowing = true
maxPriority.showDialog()
}
maxPriority.setDismissListener {
hasDialogShowing = false
showDialogByPriority()
}
}

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
dialogPriorityQueue.clear()
}
}
/**
* 定义dialog优先级
* @property priority Int
* @constructor
*/
sealed class DialogPriority(open val priority: Int) {
sealed class HomeMapFragment(override val priority: Int) : DialogPriority(priority) {
/**
* App更新
*/
object UpdateDialog : HomeMapFragment(0)

/**
* 等级提升
*/
object LevelUpDialog : HomeMapFragment(1)

/**
* 金币打卡
*/
object CoinClockInDialog : HomeMapFragment(2)
}
}

/**
* ClassName: PriorityDialogWrapper
* Description: 优先级弹窗包装类
* author Neo
* since 2021-09-15 20:20
* version 1.0
*/
class PriorityDialogWrapper(private val dialog: Dialog, private val dialogPriority: DialogPriority) : Comparable<PriorityDialogWrapper> {

private var dismissCallback: (() -> Unit)? = null

private val timestamp = SystemClock.elapsedRealtimeNanos()

init {
dialog.setOnDismissListener {
dismissCallback?.invoke()
}
}

fun isShowing(): Boolean = dialog.isShowing

fun setDismissListener(callback: () -> Unit) {
this.dismissCallback = callback
}

fun showDialog() {
dialog.show()
}

override fun compareTo(other: PriorityDialogWrapper): Int {
return when {
dialogPriority.priority > other.dialogPriority.priority -> {
// 当前对象比目标对象大,则返回 1
1
}
dialogPriority.priority < other.dialogPriority.priority -> {
// 当前对象比目标对象小,则返回 -1
-1
}
else -> {
// 若是两个对象相等,则返回 0
when {
timestamp > other.timestamp -> {
1
}
timestamp < other.timestamp -> {
-1
}
else -> {
0
}
}
}
}
}
}

使用:

AppCompatActivity

DialogPriorityUtil.bindLifeCycle(this)
DialogPriorityUtil.showDialogByPriority(...)

0 个评论

要回复文章请先登录注册