如何在Jetpack Compose中实现可独立点击展开的列表项
解决方案
问题根源是你用了一个全局的expanded状态变量,所有列表项都绑定这个变量,导致点击任意卡片时所有卡片都会同步展开/收起。要实现单卡片独立展开,需要为每个列表项维护独立的状态,以下是两种可行方案:
方案一:允许多个卡片同时展开
用Map存储每个列表项的展开状态,适合需要同时展开多个卡片的场景:
@Composable fun myList() { val myList = listOf("Canada", "China", "USA", "Pakistan") // 初始化每个国家的展开状态为false val expandedStates = rememberSaveable { mutableMapOf<String, Boolean>().apply { myList.forEach { put(it, false) } } } LazyColumn( Modifier .fillMaxWidth() .padding(10.dp) ) { items(myList) { country -> val isExpanded = expandedStates[country] ?: false ElevatedCard( modifier = Modifier .fillMaxWidth() .padding(bottom = 10.dp) .clickable { // 切换当前卡片的展开状态 expandedStates[country] = !isExpanded }, shape = CardDefaults.elevatedShape, colors = CardDefaults.elevatedCardColors(), elevation = CardDefaults.elevatedCardElevation() ) { Text(text = country) if (isExpanded) { Text(text = "Content for $country") } } } } }
方案二:仅允许一个卡片展开
保存当前展开的列表项标识(比如国家名称),同一时间只能有一个卡片处于展开状态:
@Composable fun myList() { val myList = listOf("Canada", "China", "USA", "Pakistan") // 记录当前展开的国家,null表示无展开项 val expandedCountry by rememberSaveable { mutableStateOf<String?>(null) } LazyColumn( Modifier .fillMaxWidth() .padding(10.dp) ) { items(myList) { country -> val isExpanded = expandedCountry == country ElevatedCard( modifier = Modifier .fillMaxWidth() .padding(bottom = 10.dp) .clickable { // 点击时切换:当前展开则收起,否则展开当前项 expandedCountry = if (isExpanded) null else country }, shape = CardDefaults.elevatedShape, colors = CardDefaults.elevatedCardColors(), elevation = CardDefaults.elevatedCardElevation() ) { Text(text = country) if (isExpanded) { Text(text = "Content for $country") } } } } }
内容的提问来源于stack exchange,提问作者OldDogNewTricks
相关产品推荐
相关产品推荐

