【问题标题】:Not able to show AlertDialog from onClick in Jetpack Compose无法从 Jetpack Compose 中的 onClick 显示 AlertDialog
【发布时间】:2021-04-05 11:21:09
【问题描述】:

我一直试图在 Android Jetpack Compose 的动态列表中显示 onClick 中的 onClick 中的 AlertDialog

我收到编译时错误@Composable 调用只能在 @Composable 函数的上下文中发生

下面是我的代码 sn-p :

@Preview(showBackground = true)
@Composable
fun prepareCard(card: Card) {
    MyApplicationTheme() {
        androidx.compose.material.Card() {
            Column(Modifier.clickable {
                Log.d("TAG", "clicked : " + card.name)
                val showDialog = mutableStateOf(true)

                if (showDialog.value) {
                    alert(card)
                }
                 ...
            }
        }
     }

我已经制作了alert() 可组合函数,它可以从上面的代码中调用

@Composable
fun alert(card : Card) {
    AlertDialog(
        title = {
            Text("")
        },
        text = {
            Text(text = card.name)
        }, onDismissRequest = {
        },
        confirmButton = {},
        dismissButton = {}
    )
}

如图所示,我收到编译时错误

请帮忙解决这个问题

注意:

我尝试了以下修改,它解决了编译时错误,但在点击Card时仍然没有显示AlertDialog

@Preview(showBackground = true)
@Composable
fun prepareCard(card: Card) {
    MyApplicationTheme() {
        val showDialog = mutableStateOf(false)


        if (showDialog.value) {
            alert(card)
        }

        androidx.compose.material.Card() {
            Column(Modifier.clickable {
                Log.d("kushal", "clicked : " + card.name)
                showDialog.value = true
            }) {
            ...
           }
         }

【问题讨论】:

  • 点击卡片会发生什么?
  • 什么都没有发生,它不显示AlertDialog

标签: android kotlin android-jetpack android-jetpack-compose


【解决方案1】:

使用showDialog 中的remember 解决不显示AlertDialog 的问题。

val showDialog = remember { mutableStateOf(false) }
if (showDialog.value) {
     //alert...
}
Card(){
   Column(Modifier.clickable(
     onClick = {showDialog.value = true})
   ){}
}

您还应该在 alert() 函数中处理状态。

@Composable
fun alert(name : String,
          showDialog: Boolean,
          onDismiss: () -> Unit) {
    if (showDialog) {
        AlertDialog(
            title = {
                Text("Title")
            },
            text = {
                Text(text = name)
            }, 
            onDismissRequest = onDismiss,
            confirmButton = {
                TextButton(onClick = onDismiss ) {
                    Text("OK")
                }
            },
            dismissButton = {}
        )
    }
}

并调用它:

val showDialog = remember { mutableStateOf(false) }

Card(){

    if (showDialog.value) {
        alert(name = "Name",
            showDialog = showDialog.value,
            onDismiss = {showDialog.value = false})
    }
    Column(Modifier.clickable(
        onClick = {showDialog.value = true})
    ){}
}

【讨论】:

  • 我按照你的建议实现了,它正在工作。如果我在AlertDialog 之外单击,则会关闭警报,这是预期的行为,但我无法理解 Jetpack Compose 是如何处理这个问题的。如果我在alert() 呼叫中没有通过onDismiss,那么AlertDialog 不会关闭外部点击。你能解释一下吗?
  • onDismissRequest处理:当用户试图通过点击外部或按下返回按钮来关闭Dialog时执行
【解决方案2】:

您可以像下面的代码一样更新您的代码 ->

@Composable
fun alert() {
MaterialTheme {
    Column {
    val openDialog = remember { mutableStateOf(false)  }

        Button(onClick = {
            openDialog.value = true
        }) {
            Text("Click me")
        }

        if (openDialog.value) {

            AlertDialog(
                onDismissRequest = {
                    // Dismiss the dialog when the user clicks outside the dialog or on the back
                    // button. If you want to disable that functionality, simply use an empty
                    // onCloseRequest.
                    openDialog.value = false
                },
                title = {
                    Text(text = "Dialog Title")
                },
                text = {
                    Text("Here is a text ")
                },
                confirmButton = {
                    Button(

                        onClick = {
                            openDialog.value = false
                        }) {
                        Text("This is the Confirm Button")
                    }
                },
                dismissButton = {
                    Button(

                        onClick = {
                            openDialog.value = false
                        }) {
                        Text("This is the dismiss Button")
                    }
                }
            )
        }
    }

}
}

【讨论】:

  • 但是并没有解决compile-time错误
  • 这是一个带有按钮的完整示例,当您单击按钮时,它将显示 AlertDialog
  • 你也可以从这里foso.github.io/Jetpack-Compose-Playground/material/alertdialog在喷气背包游乐场找到它
  • 我已经检查过了。我试图更新我的代码并添加了有问题的更新代码。你能检查一次吗?使用更新的代码,编译时错误不会出现,但 AlertDialog 未显示 onClick
  • 添加val showDialog = remember { mutableStateOf(false) } insted of val showDialog = mutableStateOf(false) 这将有助于解决单击时不显示对话框的问题
【解决方案3】:

这是使用状态显示对话框的推荐方式。

val openDialog = remember { mutableStateOf(true) }
val dialogWidth = 200.dp
val dialogHeight = 50.dp

if (openDialog.value) {
    Dialog(onDismissRequest = { openDialog.value = false }) {
        // Draw a rectangle shape with rounded corners inside the dialog
        Box(Modifier.size(dialogWidth, dialogHeight).background(Color.White))
    }
}

【讨论】:

    猜你喜欢
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 2011-06-21
    相关资源
    最近更新 更多