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(...)