如何在未持有AlertDialog实例的情况下判断其是否正在屏幕显示?
如何在未持有AlertDialog实例时判断它是否正在显示?
下面提供几种可行的解决方案,按推荐程度排序:
1. 全局维护Dialog实例(最稳定推荐)
如果可以提前规划,最好在创建AlertDialog时把实例保存到Activity的成员变量或者全局管理类里,之后直接用isShowing()判断状态。
改造你给出的代码:
// 在MainActivity中声明成员变量 private var exitAlertDialog: AlertDialog? = null private fun showAlertDialog() { val builder = AlertDialog.Builder(this@MainActivity) builder.setMessage("Do you want to exit ?") .setTitle("Alert !") .setCancelable(false) .setPositiveButton("Yes") { _, _ -> finish() } .setNegativeButton("No") { dialog, _ -> dialog.cancel() } exitAlertDialog = builder.create() exitAlertDialog?.show() } // 调用这个方法就能判断弹窗是否显示 fun isExitAlertShowing() = exitAlertDialog?.isShowing == true
这种方式完全依赖官方API,没有兼容性问题,是最稳妥的做法。
2. 反射读取Activity的Dialog集合
Android的Activity内部会用一个私有集合mDialogs管理所有弹出的Dialog,我们可以通过反射拿到这个集合,遍历检查是否有正在显示的AlertDialog:
fun hasShowingAlertDialog(activity: Activity): Boolean { return try { val dialogsField = Activity::class.java.getDeclaredField("mDialogs") dialogsField.isAccessible = true val dialogs = dialogsField.get(activity) as? HashSet<*> dialogs?.any { it is AlertDialog && it.isShowing } ?: false } catch (e: Exception) { e.printStackTrace() false } }
⚠️ 注意:这种方式依赖系统内部实现,不同Android版本或定制ROM可能会修改mDialogs字段名,存在兼容性风险,非必要不推荐。
3. 遍历DecorView检查子View
Dialog显示时会把自身的视图添加到Activity的Window DecorView中,我们可以通过遍历子View,检查是否存在AlertDialog相关的视图类:
fun isAlertDialogVisible(activity: Activity): Boolean { val decorView = activity.window?.decorView as? ViewGroup ?: return false return (0 until decorView.childCount).any { index -> val child = decorView.getChildAt(index) child.javaClass.name.contains("AlertDialog") } }
同样,这种方式依赖系统类名,不同厂商的定制ROM可能会修改类名结构,稳定性不如第一种方法。
内容的提问来源于stack exchange,提问作者user1831933
相关产品推荐
相关产品推荐

