You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:02:07