Search code examples
androidkotlinandroid-jetpack-composeandroid-jetpack

onClick trigger for change color of multiple buttons. JetpackCompose


I have 7 buttons in a row. each has a transparent background. I want to click on one of them and its color will change. I press again and it will come back. the same with the rest of the buttons. If the button has changed color, it means that it is pressed. Like a checkbox. After that, I would like to know which button out of 7 is pressed and which is not.

I use some functions. This just for container

@Composable
fun DaysOfWeekContainer(
color: Color,
content: @Composable () -> Unit
){
 Surface(
     modifier = Modifier
         .size(40.dp),
     shape = RectangleShape,
     border = BorderStroke(1.dp, Color.Green),
     color = color
 ){
    content()
 }
}

in this function I use the previous one and put a TextButton in it

@Composable
fun DaysOfWeekButton(
    onClick: () -> Unit,
    day: Int,
    //interactionSource: MutableInteractionSource

){
    Box(contentAlignment = Center ){
        TextButton(
            onClick = onClick,
            //interactionSource = interactionSource
        ){
            Text(CalendarData(currentDay = day).currentDay())
        }
}
}

In this use 2 previos

@Composable
fun DaysOfWeek(
    onClick: () -> Unit,
    color: Color,
){

    Row(horizontalArrangement = Arrangement.SpaceEvenly){
        for(day in 0..6){
                DaysOfWeekContainer(
                    color = color
                ){
                    DaysOfWeekButton(
                        onClick = onClick,
                        day = day
                    )
        }
    }
}

So i get row with 7 buttons

@Composable
fun MyCalScreen(){

    val stateB = remember { mutableStateOf(false)}
    val color = if (stateB.value) Color.Blue else Color.Green

    Column(verticalArrangement = Arrangement.SpaceEvenly){

        Text("_")
        Spacer(modifier = Modifier.height(10.dp))
        if(stateB.value){
            DaysOfWeek(
                onClick = { stateB.value = false },
                color = color,
            )
        }else{
            DaysOfWeek(
                onClick = { stateB.value = true },
                color = color,
            )
        }
    }
}

It works very predictably. I click on one and the color changes for all buttons. How to fix it? And how do you know which buttons are pressed?


Solution

  • Each button should maintain it's state.

    val states = remember {
        SnapshotStateList<Boolean>().also {
            for(day in 0..days) {
                it.add(false)
            }
        }
    }
    

    Complete example

    @Composable
    fun ButtonSC(
        days: Int = 6
    ) {
        val states = remember {
            SnapshotStateList<Boolean>().also {
                for(day in 0..days) {
                    it.add(false)
                }
            }
        }
        Box(
            Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Row(horizontalArrangement = Arrangement.SpaceEvenly){
                for(day in 0..days) {
                    DaysOfWeekContainer(
                        color = if (states[day])Color.Blue else Color.Green,
                    ){
                        DaysOfWeekButton(
                            onClick = {
                                states[day] = !states[day]
                            },
                            day = day
                        )
                    }
                }
            }
        }
    }