📱 Compose 列表基础

LazyColumn 性能优化
Column 与 LazyColumn 的区别

🧩 在 Jetpack Compose 中,Column 和 LazyColumn 都用于垂直排列子项,但它们的渲染策略完全不同。

特性ColumnLazyColumn
📦 渲染方式一次性渲染所有子项仅渲染可见项 + 预取
⚡ 性能表现适合少量固定元素 ( < 20 )千级列表流畅,按需合成
♻️ 回收复用无回收,全部保持活跃自动回收/复用 item 组件
🧠 内存占用随子项数量线性增长几乎恒定 (仅可见区域)
📜 滚动支持需嵌套 scrollable内置滚动、惯性、fling
🎯 适用场景表单、设置页、固定布局聊天记录、Feed、长列表
为什么需要 LazyColumn

想象一个包含 10,000 条消息的聊天界面 —— 如果使用 Column,Compose 会尝试一次性测量、布局并绘制所有 item,导致:

  • 🐢 首次渲染卡顿数秒
  • 💥 内存溢出 (OOM) 风险
  • 🔄 不必要的重组 & 重绘

LazyColumn 通过延迟组合 + 项缓存,只合成可见区域附近的 item,滚动时复用组件,让列表丝滑流畅。

Column 全部渲染 LazyColumn 可见区域 按需合成 + 缓存
基本使用示例
📋 简单 LazyColumn 列表

以下代码展示了一个带 items 的典型 LazyColumn,包含 100 个文本项:

@Composable
fun SimpleLazyList() {
    val list = (1..100).toList()

    LazyColumn(
        modifier = Modifier.padding(8.dp),
        contentPadding = PaddingValues(horizontal = 12.dp, vertical = 8.dp)
    ) {
        items(list) { index ->
            ListItemCard(index = index)
        }
    }
}

@Composable
fun ListItemCard(index: Int) {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 4.dp),
        colors = CardDefaults.cardColors(
            containerColor = Color(0xFFF7E5C2)
        ),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
    ) {
        Text(
            text = "列表项 #$index",
            modifier = Modifier.padding(16.dp),
            style = MaterialTheme.typography.bodyLarge
        )
    }
}
🧪 带不同类型 Item 的 LazyColumn

使用 itemsIndexed 或 items 结合 key 提升复用效率:

@Composable
fun MessageList(messages: List<Message>) {
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.spacedBy(6.dp)
    ) {
        itemsIndexed(
            items = messages,
            key = { _, msg -> msg.id }   // 稳定 key 避免不必要的重组
        ) { index, message ->
            MessageRow(message, index)
        }
    }
}
LazyColumn 内部架构 · 按需组合 + 缓存池
数据源 List / Flow LazyColumn 组合 (Compose) 缓存 (Cache) 屏幕可见区 仅渲染可见项

✨ 核心要点

  • Column 适合 < 20 项
  • LazyColumn 按需组合
  • 使用 key 优化重组
  • 避免在 item 中做高耗时计算
  • contentPadding 预留空间
  • LazyColumn 内置滚动