如何实现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
相关产品推荐
相关产品推荐

