如何阻止AlertDialog点击Positive Button后自动关闭?
AlertDialog点击确认按钮后无法阻止自动关闭的解决方案
问题描述
在siteListFragment.kt的else分支中尝试阻止AlertDialog自动关闭,但无论设置对话框不可取消、将Positive Button回调设为null,对话框仍会在点击确认按钮后自行关闭。
相关代码
siteListFragment.kt
override fun showAddSiteDialog() { val view: View = LayoutInflater.from(context).inflate(R.layout.dialog_site_add, null) DialogService.showWithView( requireContext(), DialogService.DialogType.INFO, false, getString(R.string.add_site), view, null, DialogService.TextWithCallback(getString(R.string.dialog_negative_cancel)){ DialogService.dismiss() }, DialogService.TextWithCallback(getString(R.string.dialog_positive_add)){ GlobalScope.launch { val editText = view.findViewById<EditText>(R.id.site_name_add) val enteredText = editText.text.toString() withContext(Dispatchers.Main) { if (siteListPresenter.addSite(enteredText)) { DialogService.dismiss() } // 此处希望阻止对话框关闭,但无效 else { editText.error = getString(R.string.network_update_error_empty_name_message) } } } } ) }
DialogService.kt
private var dialog: AlertDialog? = null var builder: AlertDialog.Builder? = null private fun create( context: Context, dialogType: DialogType, cancelable: Boolean, title: String, message: String? ) { builder = AlertDialog.Builder(context, R.style.CreativePodDialog) dialog = builder!!.create() builder!!.apply { setTitle(title) setIcon(getIcon(dialogType)) if (message != null && message != "") setMessage(message) setCancelable(cancelable) } } fun showWithView( context: Context, dialogType: DialogType, cancelable: Boolean, title: String, view: View? = null, negativeButton: TextWithCallback?, neutralButton: TextWithCallback?, positiveButton: TextWithCallback?, ) { create(context, dialogType, cancelable, title, null) builder!!.apply { setView(view) if (positiveButton != null) setPositiveButton(positiveButton.text) { _, _ -> positiveButton.callback.invoke() } if (negativeButton != null) setNegativeButton(negativeButton.text) { _, _ -> negativeButton.callback.invoke() } if (neutralButton != null) setNeutralButton(neutralButton.text) { _, _ -> neutralButton.callback.invoke() } }.show() }
问题原因
Android原生AlertDialog.Builder设置的Positive/Negative/Neutral按钮,点击后会触发系统默认的对话框关闭逻辑,该行为无法通过回调内部的代码阻止——无论回调里执行什么操作,对话框都会自动关闭。
解决方案
绕过Builder的按钮设置方法,手动为对话框的按钮绑定自定义点击事件,从而完全控制对话框的关闭时机。
修改DialogService.kt中的showWithView方法:
fun showWithView( context: Context, dialogType: DialogType, cancelable: Boolean, title: String, view: View? = null, negativeButton: TextWithCallback?, neutralButton: TextWithCallback?, positiveButton: TextWithCallback?, ) { create(context, dialogType, cancelable, title, null) builder!!.apply { setView(view) // 移除通过Builder设置按钮的代码,改为后续手动绑定 } // 创建并显示对话框 dialog = builder!!.create() dialog?.show() // 手动设置确认按钮 positiveButton?.let { btnData -> dialog?.getButton(AlertDialog.BUTTON_POSITIVE)?.apply { text = btnData.text setOnClickListener { // 仅执行回调逻辑,不自动关闭对话框 btnData.callback.invoke() } } } // 手动设置取消按钮(点击后直接关闭) negativeButton?.let { btnData -> dialog?.getButton(AlertDialog.BUTTON_NEGATIVE)?.apply { text = btnData.text setOnClickListener { btnData.callback.invoke() dialog?.dismiss() } } } // 手动设置中性按钮(按需调整关闭逻辑) neutralButton?.let { btnData -> dialog?.getButton(AlertDialog.BUTTON_NEUTRAL)?.apply { text = btnData.text setOnClickListener { btnData.callback.invoke() dialog?.dismiss() } } } }
效果说明
修改后:
- 点击确认按钮时,只会执行你传入的回调逻辑,不会自动关闭对话框
- 仅当
siteListPresenter.addSite(enteredText)返回true时,调用DialogService.dismiss()才会关闭对话框 - 进入else分支时,对话框保持打开状态,同时显示输入错误提示
内容的提问来源于stack exchange,提问作者ConfusedCoder
相关产品推荐
相关产品推荐

