首页 > 解决方案 > 在 Modifier.clickable 中使用 Composable

问题描述

我正在使用一个ListItem并且我想在用户单击它时显示一个警报对话框。我读过一种方法是创建一个值,mutableStateOf然后调用该Composable值的 if 内部,但这不起作用。

这是我正在使用的代码,Modifier.clickable因为onClick它不存在于ListItem

@ExperimentalMaterialApi
@Composable
fun UsersList() {
    Column(modifier = Modifier
        .fillMaxSize()
        .background(elevation)) {
        TopAppBar(
            title = { Text("List of users") },
            navigationIcon = {
                IconButton(onClick = { /*TODO*/ }) {
                    Icon(Icons.Filled.ArrowBack, contentDescription = null)
                }
            },
            backgroundColor = elevation2,
            contentColor = Color.White
        )
        LazyColumn() {
            item {
                val openDialog = remember { mutableStateOf(true) }

                ListItem(
                    text = { Text("Name",  color = Color.White) },
                    icon = { Icon(Icons.Filled.Face, contentDescription = null, tint = Color.White) },
                    modifier = Modifier.clickable { if(openDialog.value) { OpenAlertDialog(openDialog)} },
                    
                )
            }
        }

    }
}

@Composable
fun OpenAlertDialog(openDialog: MutableState<Boolean>) {
    AlertDialog(
        onDismissRequest = {
            openDialog.value = false
        },
        title = {
            Text(text = "Title")
        },
        text = {
            Text(
                "This area typically contains the supportive text " +
                        "which presents the details regarding the Dialog's purpose."
            )
        },
        confirmButton = {
            TextButton(
                onClick = {
                    openDialog.value = false
                }
            ) {
                Text("Confirm")
            }
        },
        dismissButton = {
            TextButton(
                onClick = {
                    openDialog.value = false
                }
            ) {
                Text("Dismiss")
            }
        }
    )
}

标签: androidkotlinandroid-jetpack-compose

解决方案


您不应该从回调中调用 Composables。而是将可组合与其他可组合函数调用放在 if 语句中。像这样的东西:

val openDialog = remember { mutableStateOf(false) } // Set initial value to false so that dialog is not displayed initially
LazyColumn {
    item {
        ListItem(
            text = { Text("Name",  color = Color.White) },
            icon = { Icon(Icons.Filled.Face, contentDescription = null, tint = Color.White) },
            modifier = Modifier.clickable { openDialog.value = true },
        )
    }
}
if(openDialog.value) {
    OpenAlertDialog(openDialog)
}

这应该有效。我想补充的一件事是,不是openDialog直接将状态传递到层次结构中,而是传递一个更新状态的 lambda。这将使OpenAlertDialog()可组合的实现与调用者分离并增加其可重用性(例如,如果您想在对话框关闭时执行一些其他操作,那么您可以这样做)。

像这样:

fun OpenAlertDialog(onDismiss(): () -> Unit) {
    AlertDialog(
        onDismissRequest = onDismiss,
        ... // Similarly for confirm and dismiss button onClick lambdas
    )
}

在调用者函数中,使用

if(openDialog.value) {
    OpenAlertDialog { openDialog.value = false }
}

推荐阅读