Search code examples
androidkotlinandroid-jetpack-composeandroid-alertdialogandroid-compose-dialog

Not able to show AlertDialog from onClick in Jetpack Compose


I have been trying to show AlertDialog from onClick of Card in dynamic list in Android Jetpack Compose.

I am getting compile time error @Composable invocations can only happen from the context of a @Composable function when doing it.

Below is my code snippet :

@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)
                }
                 ...
            }
        }
     }

I have made alert() composable function which gets called from above code

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

As shown in image, I am getting compile time error

Please help to solve this issue

Note :

I have tried like below modifications, it solved compile time error but it is still not showing AlertDialog on click of Card

@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
            }) {
            ...
           }
         }

enter image description here


Solution

  • Use the remember in your showDialog to resolve the issue of not showing the AlertDialog.

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

    Also in your Alert() function you should handle the state.

    @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 = {}
            )
        }
    }
    

    and call it with:

    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})
        ) {}
    }