Search code examples
gridviewforeachandroid-jetpack-composelazy-loading

Create LazyVerticalGrid based off enum


I've created an enum, and I want to display all the cases in this enum in a LazyVerticalGrid of buttons. However, when I use .forEach, all the buttons show the last value in the enum, instead of all the unique values. What do I need to do to resolve this?

enum class ColorsEnum(val order: Int, val rawValue: String) {
    red(0, "Red"),
    orange(1,"Orange"),
    yellow(2, "Yellow"),
    green(3, "Green"),
    blue(4, "Blue")

}



@Composable
fun LazyGridView() {

    var selectedColors by remember { mutableStateOf(arrayListOf<String>()) }
    var selectedColorsText by remember { mutableStateOf("") }

    Column (
        verticalArrangement = Arrangement.spacedBy(10.dp)
    )
    {

        Text("Selected Colors: $selectedColorsText")


        LazyVerticalGrid(
            columns = GridCells.Fixed(2),
            verticalArrangement = Arrangement.spacedBy(10.dp),
            horizontalArrangement = Arrangement.spacedBy(10.dp)
        ) {
            items(ColorsEnum.values().size) {

                ColorsEnum.values().forEach { color ->

                    Button(
                        onClick = {
                            if (selectedColors.contains(color.rawValue)) {
                                selectedColors.remove(color.rawValue)
                                selectedColorsText = selectedColors.joinToString(", ")
                            } else {
                                selectedColors.add(color.rawValue)
                                selectedColorsText = selectedColors.joinToString(", ")
                            }
                        },
                        modifier = Modifier
                            .border(
                                width = 1.dp,
                                color = Color.Black,
                                shape = RoundedCornerShape(5.dp)
                            )
                            .background(
                                shape = RoundedCornerShape(5.dp),
                                color = Color.White
                            ),
                        colors = ButtonDefaults.buttonColors(
                            backgroundColor = Color.White
                        ),

                        ) {

                        Text(
                            text = color.rawValue,
                            style = TextStyle(
                                fontWeight = FontWeight.Bold,
                            ),
                        )


                    }
                }

            }
        }
    }

}

enter image description here


Solution

  • You are iterating twice over your items, when you use items(colorsEnum.values().size) this iterates over the items, then you do a 2nd iteration within the items. You have to remove 1 of the iterations, as shown here

    @RequiresApi(Build.VERSION_CODES.O)
    @Preview
    @Composable
    fun LazyGridView() {
    
        var selectedColors by remember { mutableStateOf(arrayListOf<String>()) }
        var selectedColorsText by remember { mutableStateOf("") }
    
        Column(
            verticalArrangement = Arrangement.spacedBy(10.dp)
        )
        {
    
            Text("Selected Colors: $selectedColorsText")
    
    
            LazyVerticalGrid(
                columns = GridCells.Fixed(2),
                verticalArrangement = Arrangement.spacedBy(10.dp),
                horizontalArrangement = Arrangement.spacedBy(10.dp)
            ) {
                items(ColorsEnum.values()) { color ->
    
                    Button(
                        onClick = {
                            if (selectedColors.contains(color.rawValue)) {
                                selectedColors.remove(color.rawValue)
                                selectedColorsText = selectedColors.joinToString(", ")
                            } else {
                                selectedColors.add(color.rawValue)
                                selectedColorsText = selectedColors.joinToString(", ")
                            }
                        },
                        modifier = Modifier
                            .border(
                                width = 1.dp,
                                color = Color.Black,
                                shape = RoundedCornerShape(5.dp)
                            )
                            .background(
                                shape = RoundedCornerShape(5.dp),
                                color = Color.White
                            ),
                        colors = ButtonDefaults.buttonColors(
                            containerColor = Color.Blue
                        ),
    
                        ) {
    
                        Text(
                            text = color.rawValue,
                            style = TextStyle(
                                fontWeight = FontWeight.Bold,
                            ),
                        )
                    }
                }
            }
        }
    }