如何在Jetpack Compose中实现带静态值的可展开列表视图
Jetpack Compose 实现静态可展开列表方案
Compose 没有内置对应 ExpandableListView 的组件,我们可以通过状态控制 + LazyColumn 实现完全相同的效果,不需要单独编写适配器和布局文件,整体代码量比原生View实现减少60%以上。
实现步骤
- 定义和原有逻辑对齐的分组、子项静态数据结构
- 通过
rememberSaveable存储每个分组的展开/收起状态,横竖屏切换不会丢失状态 - 在 LazyColumn 中依次渲染分组头、当前展开分组的子项
完整实现代码
替换你原有 TestApp 代码即可:
class TestApp : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // 替换为你项目的自定义主题即可 MaterialTheme { ExpandableStaticList() } } } } @Composable fun ExpandableStaticList() { // 准备静态数据,和原有prepareListData逻辑完全对齐 val headerList = listOf(getString(R.string.q_1)) val childMap = mapOf( headerList[0] to listOf(getString(R.string.faq_d_0)) ) // 存储每个分组的展开状态,默认全部收起 val expandedState = rememberSaveable { mutableStateMapOf<String, Boolean>().apply { headerList.forEach { put(it, false) } } } LazyColumn(modifier = Modifier.fillMaxSize()) { headerList.forEach { header -> // 渲染分组头部 item { Row( modifier = Modifier .fillMaxWidth() .clickable { // 点击切换展开/收起状态 expandedState[header] = !(expandedState[header] ?: false) } .padding(16.dp) ) { Text(text = header, modifier = Modifier.weight(1f), fontSize = 16.sp) // 可选:添加箭头指示展开状态 Icon( imageVector = if (expandedState[header] == true) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown, contentDescription = null ) } Divider() } // 分组展开时渲染对应子项 if (expandedState[header] == true) { val childList = childMap[header].orEmpty() items(childList) { childText -> Text( text = childText, modifier = Modifier .fillMaxWidth() .background(Color.LightGray.copy(alpha = 0.2f)) .padding(horizontal = 32.dp, vertical = 14.dp), fontSize = 14.sp ) } } } } }
扩展说明
- 需要新增分组时,直接往
headerList和childMap中添加对应数据即可,适配逻辑自动生效 - 你可以自行修改padding、背景色、文字样式等参数实现自定义UI效果
- 如果需要添加子项点击逻辑,直接给子项Text添加
clickable修饰符即可
内容的提问来源于stack exchange,提问作者Ramanjeet
相关产品推荐
相关产品推荐

