如何让Android Kotlin中的AlertDialog静态函数返回布尔值
问题描述
我想编写一个带有AlertDialog的静态函数,让它返回布尔值。
在C#里的实现是这样的:
DialogResult dialogResult = MessageBox.Show("Sure", "Some Title", MessageBoxButtons.YesNo); if(dialogResult == DialogResult.Yes) { //do something } else if (dialogResult == DialogResult.No) { //do something else }
我在Kotlin里写了一个包含companion object的类:
class Dialog { companion object { fun question(context: Context, title: String, message: String) { AlertDialog.Builder(context).apply { setIcon(R.drawable.ic_question) setTitle(title) setMessage(message) setPositiveButton("YES", DialogInterface.OnClickListener { dialog, which -> }) setNegativeButton("NO", DialogInterface.OnClickListener { dialog, which -> }) }.show() } } }
我希望让question函数返回布尔值,然后能在Activity里这样使用:
if(Dialog.question(this,"Title", "Message")) { //something } else { //something }
请问这是否可行?
解答
这种直接返回布尔值的写法不可行。
原因是Android的AlertDialog是异步组件:当你调用show()方法后,函数会立刻执行完毕并返回,不会等待用户点击按钮。所以如果强行让question函数返回布尔值,它会在用户做出选择前就返回一个默认值,完全达不到你想要的效果。
你可以通过以下两种方式实现类似需求:
方式1:使用回调函数
修改question函数,传入一个lambda表达式,在用户点击按钮时触发回调:
class Dialog { companion object { fun question( context: Context, title: String, message: String, onResult: (Boolean) -> Unit ) { AlertDialog.Builder(context).apply { setIcon(R.drawable.ic_question) setTitle(title) setMessage(message) setPositiveButton("YES") { _, _ -> onResult(true) } setNegativeButton("NO") { _, _ -> onResult(false) } }.show() } } }
在Activity中这样调用:
Dialog.question(this, "Title", "Message") { result -> if (result) { // 用户点击了YES的逻辑 } else { // 用户点击了NO的逻辑 } }
方式2:使用协程挂起函数(推荐)
如果你的项目使用了Kotlin协程,可以把question写成挂起函数,通过CompletableDeferred等待用户选择,实现类似同步的写法:
class Dialog { companion object { suspend fun question( context: Context, title: String, message: String ): Boolean { val deferred = CompletableDeferred<Boolean>() AlertDialog.Builder(context).apply { setIcon(R.drawable.ic_question) setTitle(title) setMessage(message) setPositiveButton("YES") { _, _ -> deferred.complete(true) } setNegativeButton("NO") { _, _ -> deferred.complete(false) } // 对话框被取消时默认返回false setOnCancelListener { deferred.complete(false) } }.show() return deferred.await() } } }
在Activity的协程作用域中调用(比如使用lifecycleScope):
lifecycleScope.launch { val result = Dialog.question(this@MainActivity, "Title", "Message") if (result) { // 用户点击YES的逻辑 } else { // 用户点击NO或取消的逻辑 } }
内容的提问来源于stack exchange,提问作者marios160
相关产品推荐
相关产品推荐

