Home > Software design >  Kotlin Jetpack Compose, Card, change color on click
Kotlin Jetpack Compose, Card, change color on click

Time:04-16

I cant get the Card in the LazyColumn to check if the number is in val guestNumbers and then change the color on the Card.

But the numbers in val guestNumbers changes on startup.

Is the Card the right stuff to use or should i use buttons?

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {

            val guestNumbers = rememberSaveable {
                mutableStateOf(mutableSetOf<Int>(10,11,2,22))
            }

            NumberGuessingGameTheme {

                Scaffold(
                    topBar = {
                        TopAppBar {

                        }
                    }
                ) {
                    Row(modifier = Modifier.fillMaxSize()
                    ) {

                        Box(
                            modifier = Modifier
                                .fillMaxSize()
                                .weight(4f)
                                .background(color = Color.LightGray)
                        ) {
                            Text(
                                text = "1F",
                                style = MaterialTheme.typography.caption
                            )
                        }

                        Box(
                            modifier = Modifier
                                .fillMaxSize()
                                .weight(1f)
                                .background(color = Color.LightGray)
                        ) {
                            LazyColumn {
                                items(1000   1) {
                                    Card(modifier = Modifier
                                        .fillMaxSize()
                                        .padding(5.dp)
                                        //.background(if ("$it".toInt() !in guestNumbers.value) Color.Green else Color.Red)
                                        .clickable {
                                            guestNumbers.value.add("$it".toInt())
                                            Log.d("Tag", "${guestNumbers.value}")
                                        },
                                        elevation = 10.dp,
                                        backgroundColor = if ("$it".toInt() in guestNumbers.value) Color.Red else Color.LightGray
                                    ) {
                                        Text(text = "$it", fontSize = 28.sp, textAlign = TextAlign.Center)

                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

CodePudding user response:

mutableStateOf cannot track changes of the underlaying object. It can only trigger recomposition when you replace its value with an other object.

You can store an immutable set, create a modifiable copy to change it, and set the new value to your mutable state. This will create a new object.

var guestNumbers by rememberSaveable {
    mutableStateOf(setOf(10,11,2,22))
}

Button({
    val mutableSet = guestNumbers.toMutableSet()
    mutableSet.add(if (Random.nextBoolean()) 2 else Random.nextInt())
    guestNumbers = mutableSet.toSet()
}) {
    Text(guestNumbers.toString())
}

Note, that if you'll face same problem with a list, you gonna need to call .toImmutableList(), because .toList() is only erasing the type and not actually creating a new object if called on a mutable list.

  • Related