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

如何让ConfirmationDialog同步返回结果?多场景复用方案咨询

问题解决方案

一、关于同步返回对话框结果的可行性

直接通过val returnValue = dialog.show()同步获取结果不可行,因为Android对话框是异步交互组件——UI操作必须在主线程执行,同步阻塞主线程会触发ANR(Application Not Responding),违反Android的UI线程规则。所有用户交互(比如点击确认/取消)都是异步回调触发的,无法直接同步返回结果。

二、优雅复用确认对话框的实现方案

1. 用Kotlin协程封装异步结果(推荐)

借助CompletableDeferred将回调式的异步结果转为挂起函数,实现类似同步的写法,同时不阻塞主线程:

步骤1:封装通用确认对话框的挂起函数

suspend fun showConfirmationDialog(
    context: Context,
    title: String,
    message: String
): Boolean {
    val deferred = CompletableDeferred<Boolean>()
    AlertDialog.Builder(context)
        .setTitle(title)
        .setMessage(message)
        .setPositiveButton("确认") { _, _ ->
            deferred.complete(true)
        }
        .setNegativeButton("取消") { _, _ ->
            deferred.complete(false)
        }
        .setOnCancelListener {
            deferred.complete(false)
        }
        .show()
    return deferred.await()
}

步骤2:在RecyclerView的Adapter中调用(需在协程作用域)

在Adapter的点击事件里,通过lifecycleScope或者viewModelScope启动协程:

// 假设Adapter持有LifecycleOwner引用(比如从Activity/Fragment传入)
button.setOnClickListener {
    lifecycleOwner.lifecycleScope.launch {
        val isConfirmed = showConfirmationDialog(
            context = itemView.context,
            title = "删除确认",
            message = "确定要删除这条数据吗?"
        )
        if (isConfirmed) {
            // 执行当前场景的操作,比如删除数据
            deleteItem(position)
        }
    }
}

这种方式不需要在MainActivity中标记操作类型,每个场景直接在点击回调里处理自己的逻辑,完全解耦。

2. 用高阶函数传递回调逻辑

如果不想用协程,可以把确认后的操作作为高阶函数传入对话框,直接在对话框的按钮回调中执行:

步骤1:封装带回调的通用对话框

fun showConfirmationDialog(
    context: Context,
    title: String,
    message: String,
    onConfirm: () -> Unit,
    onCancel: () -> Unit = {}
) {
    AlertDialog.Builder(context)
        .setTitle(title)
        .setMessage(message)
        .setPositiveButton("确认") { _, _ ->
            onConfirm()
        }
        .setNegativeButton("取消") { _, _ ->
            onCancel()
        }
        .setOnCancelListener {
            onCancel()
        }
        .show()
}

步骤2:在Adapter中调用

button.setOnClickListener {
    showConfirmationDialog(
        context = itemView.context,
        title = "编辑确认",
        message = "确定要修改这条数据吗?",
        onConfirm = {
            // 执行编辑操作
            editItem(position)
        },
        onCancel = {
            // 可选:取消后的逻辑
        }
    )
}

这种写法同样不需要在MainActivity中维护状态变量,每个场景的操作逻辑直接内联传递,清晰且复用性强。

3. 优化原接口监听方案

如果坚持用接口方式,也可以通过场景枚举+接口携带参数来替代主Activity的变量标记:

// 定义操作场景枚举
enum class DialogAction { DELETE, EDIT, SHARE }

// 定义带场景参数的接口
interface DialogCallback {
    fun onActionConfirmed(action: DialogAction, position: Int)
}

// 在Adapter中调用时传入场景
button.setOnClickListener {
    showConfirmationDialog(
        context = itemView.context,
        title = "分享确认",
        message = "确定要分享这条内容吗?",
        callback = activity as DialogCallback,
        action = DialogAction.SHARE,
        position = position
    )
}

// MainActivity实现接口时根据场景处理
override fun onActionConfirmed(action: DialogAction, position: Int) {
    when(action) {
        DialogAction.DELETE -> deleteItem(position)
        DialogAction.EDIT -> editItem(position)
        DialogAction.SHARE -> shareItem(position)
    }
}

这种方式虽然还是用接口,但通过枚举和参数明确操作类型,不需要在Activity中维护额外的标记变量,比原方案更清晰。


内容的提问来源于stack exchange,提问作者Owlon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:22:51