Using Jetpack Compose state management, I want to change background
of Card
in scrollable
list, when user clicks on AlertDialog
As shown in below code, I have stored state
as cardState
with remember
When user is clicking on AlertDialog
positive button, I am changing the state value.
I am expecting that after the value of state is changed, Recomposition would take place and UI will be updated. The background color is getting set based on this state
cardState.value.isInCart
Code :
@Preview(showBackground = true)
@Composable
fun prepareCard(card: Card) {
// Remembering card state for adding in cart
val cardState = remember { mutableStateOf(card) }
var bgColor = R.color.white
if (cardState.value.isInCart) { // Setting background color based on state here
bgColor = android.R.color.holo_blue_light
}
MyApplicationTheme() {
androidx.compose.material.Card(
modifier = Modifier.background(color = Color(bgColor)) // using background color here
) {
// Remembering boolean for alert dialog
val showDialog = remember { mutableStateOf(false) }
if (showDialog.value) {
alert(cardState, { showDialog.value = false }) // showing alert from here
}
Column(Modifier.clickable {
showDialog.value = true // on click of Card, changing showDialog state value, which will trigger Alert dialog to be displayed
}) {
Image(
modifier = Modifier
.fillMaxWidth()
.height(200.dp),
contentScale = ContentScale.Fit,
painter = painterResource(id = card.imageId),
contentDescription = ""
)
Text(text = card.name)
}
}
}
}
@Composable
fun alert(cardState: MutableState<Card>, dismiss: () -> Unit = { }) {
AlertDialog(
title = {
Text("SmartPhone")
},
text = {
Row(
modifier = Modifier
.horizontalScroll(rememberScrollState(0))
) {
Text(text = cardState.value.name)
Image(
modifier = Modifier
.width(200.dp)
.height(200.dp),
contentScale = ContentScale.Fit,
painter = painterResource(id = cardState.value.imageId),
contentDescription = cardState.value.name
)
}
}, onDismissRequest = dismiss, // This will help to dismiss alert from outside touch
confirmButton = {
Button(onClick = {
// Add this item in cart === Changing the state here on positive button click, now I am expecting that after Alert will be dismisssed with outside touch then the Card's background would change to holo blue because isInCard is true
cardState.value.isInCart = true
}) { Text("Ok") }
},
dismissButton = { Button(onClick = {}) { Text("Cancel") } }
)
First of all in the Card
use backgroundColor
instead of Modifier.background
Card(
backgroundColor = bgColor
)
Then use something different:
MutableState
for the card.isInCart
not the card-objSomething like:
@Composable
fun prepareCard(card: Card) {
//Use a MutableState for the card.isInCart not the card-obj
val inCartState = remember { mutableStateOf(card.isInCart) }
//Use colorResource
var bgColor = colorResource(R.color.white)
if (inCartState.value) {
bgColor = Color.Blue
}
Card(
backgroundColor = bgColor
) {
// Remembering boolean for alert dialog
val showDialog = remember { mutableStateOf(false) }
if (showDialog.value) {
alert(
showDialog = showDialog.value,
onConfirm = { inCartState.value = true},
onDismiss = { showDialog.value = false })
}
Column(Modifier.clickable {
showDialog.value = true // on click of Card, changing showDialog state value, which will trigger Alert dialog to be displayed
}) {
Image(
//...
)
Text(text = /*...*/)
}
}
}
and
@Composable
fun alert(showDialog: Boolean,
onConfirm: () -> Unit,
onDismiss: () -> Unit) {
if (showDialog) {
AlertDialog(
title = { Text("SmartPhone")},
text = {
//..
},
onDismissRequest = onDismiss,
confirmButton = {
Button(onClick = onConfirm ){ Text("Ok") }
},
dismissButton = {
Button(onClick = onDismiss ){ Text("Cancel") } }
)
}
}