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

如何实现Jetpack Compose中LazyColumn列表项的单选互斥功能

Jetpack Compose LazyColumn 单选互斥实现方案

核心逻辑说明

  • 单选互斥的核心是仅维护唯一的当前选中项标识,点击新项时直接替换该标识,天然实现其余项自动取消选中的效果
  • InteractionSource属于可选扩展能力,仅当你需要自定义列表项的交互反馈(比如自定义水波纹效果、监听按压/聚焦态联动)时才需要接入,基础单选逻辑不需要依赖该能力

基础实现代码

// 1. 定义列表数据结构,保证每个项有唯一ID
data class ListItem(
    val id: Int,
    val content: String
)

@Composable
fun SingleSelectLazyColumn() {
    // 2. 维护唯一选中状态,存储当前选中的项ID,null表示无选中项
    var selectedItemId by remember { mutableStateOf<Int?>(null) }
    // 模拟列表数据源
    val list = remember {
        List(20) { ListItem(id = it, content = "列表项 $it") }
    }

    LazyColumn {
        items(list, key = { it.id }) { item ->
            // 3. 绑定选中状态到UI样式
            val isSelected = item.id == selectedItemId
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable {
                        // 4. 点击时更新选中状态,直接替换为当前项ID,自动实现互斥
                        selectedItemId = if (isSelected) null else item.id
                    }
                    .background(if (isSelected) Color.Blue else Color.Transparent)
                    .padding(16.dp)
            ) {
                Text(
                    text = item.content,
                    color = if (isSelected) Color.White else Color.Black
                )
            }
        }
    }
}

接入InteractionSource的扩展实现

如果需要自定义交互反馈,可按以下方式接入InteractionSource:

@Composable
fun SingleSelectLazyColumnWithInteraction() {
    var selectedItemId by remember { mutableStateOf<Int?>(null) }
    val list = remember { List(20) { ListItem(id = it, content = "列表项 $it") } }

    LazyColumn {
        items(list, key = { it.id }) { item ->
            val isSelected = item.id == selectedItemId
            // 每个列表项持有独立的InteractionSource
            val interactionSource = remember { MutableInteractionSource() }

            // 可选:如果需要手动控制选中态的交互事件发射
            LaunchedEffect(isSelected) {
                if (isSelected) {
                    interactionSource.emit(PressInteraction.Press(Offset.Zero))
                    interactionSource.emit(PressInteraction.Release(PressInteraction.Press(Offset.Zero)))
                }
            }

            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable(
                        interactionSource = interactionSource,
                        // 可自定义水波纹效果
                        indication = rememberRipple(color = Color.Red)
                    ) {
                        selectedItemId = if (isSelected) null else item.id
                    }
                    .background(if (isSelected) Color.Blue else Color.Transparent)
                    .padding(16.dp)
            ) {
                Text(
                    text = item.content,
                    color = if (isSelected) Color.White else Color.Black
                )
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:06:05