Jetpack 撰写状态管理,无法更改卡的背景颜色

Jetpack compose state management, unable to change background color of Card

使用 Jetpack Compose 状态管理,当用户点击 AlertDialog

时,我想更改 scrollable 列表中 Cardbackground

如以下代码所示,我已将 state 存储为 cardStateremember

当用户点击 AlertDialog 肯定按钮时,我正在更改状态值。

我期待状态值改变后,重组会发生并且UI会被更新。正在根据此状态设置背景颜色

cardState.value.isInCart

代码:

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

首先在Card中使用backgroundColor代替Modifier.background

   Card(
       backgroundColor = bgColor
    ) 

然后使用不同的东西:

  • card.isInCart 使用 MutableState 而不是卡片对象
  • 在 Jetpack Compose 中应用状态提升的一般模式

类似于:

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

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