Jetpack compose 状态管理,无法更改 Card 的背景颜色

问题描述 投票:0回答:2

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

background
 时,我想更改 
Card
 列表中 
scrollable
AlertDialog

如下面的代码所示,我将

state
存储为
cardState
并使用 remember

当用户单击

AlertDialog
肯定按钮时,我正在更改状态值。

我期望状态值改变后,会发生Recomposition并且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") } }
    )
android android-jetpack-compose android-jetpack android-compose-textfield android-compose-card
2个回答
2
投票

首先在

Card
中使用
backgroundColor
代替
Modifier.background

   Card(
       backgroundColor = bgColor
    ) 

然后使用不同的东西:

  • 使用
    MutableState
    作为
    card.isInCart
    而不是卡片对象
  • 在 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") } }
        )
    }
}

0
投票

对于 Compose Material3,请使用以下属性。

import androidx.compose.material3.Card

 Card(
    shape = RoundedCornerShape(dimen_4),
    modifier = Modifier
        .padding(bottom = dimen_8)
        .clickable(onClick = {})
        .fillMaxWidth(),
    elevation = CardDefaults.cardElevation(
        defaultElevation = dimen_4,
    ),
    colors = CardDefaults.cardColors(
        containerColor = OnTertiaryLight, // change color here Color.White
    )
© www.soinside.com 2019 - 2024. All rights reserved.