Compose Tree List
compose 树形列表,支持上万数据


@Composable
fun <T> TreeLazyColumn(
modifier: Modifier = Modifier,
state: TreeState<T>,
currentId: String? = null,
indentWidth: Dp = 16.dp,
itemContent: @Composable (
node: TreeNode<T>,
level: Int,
isExpanded: Boolean,
isCurrent: Boolean,
toggle: () -> Unit
) -> Unit
) {
val visibleNodes by remember { derivedStateOf { state.visibleNodes() } }
LazyColumn(modifier) {
items(
items = visibleNodes,
key = { it.node.id }
) { flatNode ->
val node = flatNode.node
val level = flatNode.level
val isExpanded = state.isExpanded(node.id)
val isCurrent = currentId == node.id
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = indentWidth * level)
) {
itemContent(
node,
level,
isExpanded,
isCurrent
) {
state.toggle(node.id)
}
}
}
}
}
class TreeState<T>(
nodes: List<TreeNode<T>>
) {
private val nodeMap = nodes.associateBy { it.id }.toMutableMap()
private val childrenMap = nodes.groupBy { it.parentId }
var expandedIds = mutableStateListOf<String>()
private set
fun toggle(id: String) {
if (expandedIds.contains(id)) expandedIds.remove(id)
else expandedIds.add(id)
}
fun isExpanded(id: String) = expandedIds.contains(id)
fun visibleNodes(): List<FlatTreeNode<T>> {
val result = mutableListOf<FlatTreeNode<T>>()
fun addChildren(parentId: String?, level: Int) {
val children = childrenMap[parentId] ?: return
children.forEach { node ->
result.add(FlatTreeNode(node, level))
if (isExpanded(node.id)) {
addChildren(node.id, level + 1)
}
}
}
addChildren(null, 0)
return result
}
}
Usage
val treeState = remember { TreeState(nodes) }
var currentId by remember { mutableStateOf<String?>(null) }
TreeLazyColumn(
modifier = modifier
.fillMaxSize(),
state = treeState,
currentId = currentId
) { node, level, expanded, isCurrent, toggle ->
val hasChildren = remember(node.id) {
nodes.any { it.parentId == node.id }
}
DefaultTreeItem(
title = node.data,
level = level,
isExpanded = expanded,
isCurrent = isCurrent,
hasChildren = hasChildren,
onToggle = toggle,
onClick = { currentId = node.id },
)
}
github 地址
喜欢的朋友可以点个星星