You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于枚举创建LazyVerticalGrid:按钮显示重复枚举值的问题解决

问题:LazyVerticalGrid中枚举按钮全部显示最后一个值的解决方法

你创建了ColorsEnum枚举类,希望在Jetpack Compose的LazyVerticalGrid组件中以按钮形式展示该枚举的所有实例,但使用forEach遍历枚举后,所有按钮均显示枚举中的最后一个值,而非各自对应的唯一值。以下是你的原代码:

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,
                            ),
                        )
                    }
                }
            }
        }
    }
}

错误原因

你当前的写法存在逻辑错误:

  • 使用items(ColorsEnum.values().size)会创建与枚举数量相同的item位置,但在每个item内部又通过forEach遍历所有枚举值,相当于每个item位置都渲染了所有枚举的按钮,后渲染的按钮会覆盖前面的,最终每个位置只显示最后一个枚举的按钮,所以视觉上所有按钮都是最后一个值。

解决方法

直接让LazyVerticalGrid的items遍历枚举数组本身,每个item对应一个枚举实例,避免重复渲染。同时可以优化状态更新逻辑,用derivedStateOf自动生成选中文本,无需手动更新:

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(mutableSetOf<String>()) }
    // 用derivedStateOf自动计算选中文本,无需手动更新
    val selectedColorsText by remember {
        derivedStateOf {
            selectedColors.joinToString(", ")
        }
    }

    Column(
        verticalArrangement = Arrangement.spacedBy(10.dp),
        modifier = Modifier.padding(10.dp)
    ) {
        Text("Selected Colors: $selectedColorsText")

        LazyVerticalGrid(
            columns = GridCells.Fixed(2),
            verticalArrangement = Arrangement.spacedBy(10.dp),
            horizontalArrangement = Arrangement.spacedBy(10.dp)
        ) {
            // 直接遍历枚举数组,每个item对应一个枚举实例
            items(ColorsEnum.values()) { color ->
                Button(
                    onClick = {
                        if (selectedColors.contains(color.rawValue)) {
                            selectedColors.remove(color.rawValue)
                        } else {
                            selectedColors.add(color.rawValue)
                        }
                    },
                    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,
                        ),
                    )
                }
            }
        }
    }
}

关键改动点

  1. 修正LazyVerticalGrid的items逻辑:将items(ColorsEnum.values().size)改为items(ColorsEnum.values()),直接绑定枚举数组,每个item对应一个枚举值,避免重复渲染。
  2. 优化状态存储:将arrayListOf<String>()改为mutableSetOf<String>(),因为选中状态是唯一的,Set的contains和add/remove操作效率更高。
  3. 自动计算选中文本:使用derivedStateOf监听selectedColors的变化,自动生成拼接后的文本,无需手动调用joinToString更新selectedColorsText,简化状态管理。

内容的提问来源于stack exchange,提问作者GVG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:58:24