Android: Column 和LazyColumn的区别

11 阅读2分钟

一、Column 和LazyColumn的区别:

1、LazyColumn 和 Column 核心区别解析

LazyColumn 和 Column 都是 Compose 中用于垂直排列子组件的容器,但设计目标和性能表现天差地别 ——Column 是 “一次性渲染所有子项” 的简单布局,LazyColumn 是 “按需渲染可见项” 的高性能滚动列表

特性ColumnLazyColumn
渲染逻辑一次性渲染所有子组件(不管是否在屏幕可见)只渲染屏幕可见的子组件,滑动时动态回收 / 创建
滚动能力无内置滚动(需嵌套 VerticalScrollbar + modifier.verticalScroll()内置垂直滚动(无需额外配置)
性能表现子项少(<20)时流畅;子项多(>50)时卡顿、内存溢出子项再多(上千 / 上万)也流畅,内存占用极低
核心定位简单垂直布局(比如表单、少量元素排列)高性能长列表(比如联系人、商品列表、消息列表)
API 风格直接传子组件(Column { Text() ; Button() }用 DSL 语法(LazyColumn { items(数据) { ... } }
状态管理无内置滚动状态(需手动监听)内置 LazyListState(控制滚动、监听位置)
特殊能力无(仅基础布局)支持粘性头部、网格布局、精准滚动到指定项

2、Column 示例(一次性渲染所有子项)

@Composable
fun ColumnDemo() {
    // 模拟1000条子项
    val dataList = List(1000) { "Column 子项 $it" }

    // Column 会一次性渲染1000个Text,启动时卡顿严重
    Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState()) // 手动加滚动
    ) {
        dataList.forEach { item ->
            Text(text = item, modifier = Modifier.padding(8.dp))
        }
    }
}
  • 执行效果:启动页面时,Compose 会立刻创建 1000 个 Text 组件,内存占用飙升,页面卡顿甚至无响应;

  • 滚动体验:滚动时无复用,滑动越久越卡。

3、LazyColumn 示例(按需渲染可见项)

@Composable
fun LazyColumnDemo() {
    val dataList = List(1000) { "LazyColumn 子项 $it" }

    // LazyColumn 只渲染屏幕可见的10-20个Text,启动秒开
    LazyColumn {
        items(dataList) { item ->
            Text(text = "$item", modifier = Modifier.padding(8.dp))
        }
    }
}
  • 执行效果:启动页面时,仅创建屏幕能显示的 10-20 个 Text,内存占用极低,页面秒开;

  • 滚动体验:滑动时销毁出屏的子项、创建入屏的子项,全程流畅无卡顿。

二、使用场景选型(直接套用)

1、✅ 用 Column 的场景(满足一个即可)

  1. 子组件数量少且固定(比如 <20 个,如表单、导航栏、页面头部);
  2. 不需要滚动(比如页面内的局部垂直排列);
  3. 子组件高度不固定,且需要完整布局计算(比如复杂的嵌套布局)。
// 页面头部(少量元素)
    Column(
    modifier = Modifier.fillMaxWidth(),
    horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("页面标题", fontSize = 20.sp)
        Text("副标题", fontSize = 14.sp)
        Button(onClick = { /* 操作 */ }) {
            Text("按钮")
        }
    }

2、用 LazyColumn 的场景(满足一个即可)

  1. 子组件数量多且动态(比如 >20 个,如商品列表、聊天记录、联系人);
  2. 需要高性能滚动(避免卡顿 / 内存溢出);
  3. 需要特殊列表能力(粘性头部、精准滚动到指定项、网格布局)。
// 商品列表(100+ 项)
    LazyColumn {
        // 粘性头部
        stickyHeader {
            Text("热销商品", modifier = Modifier.background(Color.Gray).padding(8.dp))
        }
        // 动态列表项
        items(商品数据列表) { goods ->
            GoodsItem(goods) // 自定义商品项UI
        }
    }