【Jetpack Compose基础语法学与练】第7课 if条件渲染 + 列表基础(LazyColumn)

前言

上一课学习了 TextField 文本输入,掌握字符串状态、 value 与 onValueChange 的单向数据流。

本课学习两大常用能力:if条件渲染(根据状态决定组件是否显示)、LazyColumn懒加载列表(长列表只渲染屏幕可见项,性能高效)。

前置:完成1~6课,掌握状态、可组合函数、基础布局

一、完整可运行示例源码

kotlin 复制代码
  
package com.example.composefirst

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ListDemoPage()
        }
    }
}

@Composable
fun ListDemoPage() {
    // 输入文本状态
    var inputText by remember { mutableStateOf("") }
    // 待办列表,字符串集合
    var todoList by remember { mutableStateOf(mutableListOf<String>()) }

    Column(modifier = Modifier.padding(20.dp)) {
        TextField(
            value = inputText,
            onValueChange = { inputText = it },
            label = { Text("输入待办事项") }
        )
        Spacer(modifier = Modifier.height(12.dp))

        Button(onClick = {
            if(inputText.isNotBlank()){
                todoList.add(inputText)
                inputText = ""
            }
        }) {
            Text("添加待办")
        }
        Spacer(modifier = Modifier.height(16.dp))

        // if条件渲染:列表为空时显示提示文字
        if(todoList.isEmpty()){
            Text("暂无待办,请添加任务")
        }else{
            // LazyColumn 懒加载列表
            LazyColumn {
                items(todoList){ item ->
                    Text(text = "· $item", modifier = Modifier.padding(vertical = 4.dp))
                }
            }
        }
    }
}

@Preview
@Composable
fun ListPreview() {
    ListDemoPage()
}
 

二、逐行代码解读

  1. if条件渲染
kotlin 复制代码
  
if(todoList.isEmpty()){
    Text("暂无待办,请添加任务")
}else{
    LazyColumn { ... }
}
 

Compose可组合函数内部可以直接使用Kotlin的 if 判断。

  • 条件成立:渲染if分支内的组件;
  • 条件不成立:渲染else分支组件;

原理:状态变化触发重组,重新执行函数,根据条件动态选择渲染哪一段UI。

注意: if 必须返回同类型的组件树,不能返回不同类型。

  1. LazyColumn 懒加载纵向列表
    Column 会一次性渲染全部子项,数据量大时卡顿。
    LazyColumn 是懒加载容器:只渲染当前屏幕可见的条目,滑出屏幕的条目会被回收,适合长列表。
  • items(集合) :批量遍历集合,为集合中每一项生成UI。
  • 对比: Column 一次性加载全部; LazyColumn 按需加载。
  1. 待办列表状态
kotlin 复制代码
  
var todoList by remember { mutableStateOf(mutableListOf<String>()) }
 

mutableListOf 可变集合,但是注意:修改集合内部元素,不会触发重组。

本示例 todoList.add() 可以刷新界面,是因为mutableStateOf会监听这个list引用变化;

易错点:如果只是修改list内部元素,引用不变,Compose不会感知,推荐使用 mutableStateListOf 专门做列表状态。

  1. 添加按钮逻辑
    点击按钮,判断输入不为空,添加到列表,清空输入框;状态变更触发重组,列表自动刷新。

三、补充知识点:mutableStateListOf(推荐列表状态)

上面示例的优化写法,专门的可观察列表,修改内部元素也能触发重组:

kotlin 复制代码
  
var todoList = remember { mutableStateListOf<String>() }

直接调用 todoList.add() 、 todoList.remove() ,自动通知Compose刷新界面,开发列表优先使用这个。

四、综合练习题

填空题

  1. Compose中实现根据状态动态展示UI,可直接使用Kotlin的________语句。
  2. 适合大量数据、按需渲染的纵向列表组件是________。
  3. LazyColumn遍历集合生成列表项,使用________函数。

答案与解析

  1. if ;解析:Compose是函数式UI,直接在代码内用if做条件渲染。
  2. LazyColumn ;解析:懒加载列表,只渲染屏幕可见条目,适合长数据。
  3. items ;解析:LazyColumn内部DSL,遍历集合生成每一行UI。

判断题

  1. Column适合上万条数据列表,性能和LazyColumn一样。()

答案:错误。理由:Column一次性渲染所有子元素,大量数据会造成页面卡顿;LazyColumn懒加载回收视图。

  1. if条件渲染,条件改变后,Compose会触发重组自动切换UI。()

答案:正确。理由:状态变更触发重组,重新执行可组合函数,if判断重新执行,切换界面。

  1. mutableStateListOf 列表,调用add添加元素,会自动触发界面重组刷新。()

答案:正确。理由:mutableStateListOf是Compose专用可观察列表,增删元素会通知框架刷新UI。

简答题

  1. 简述 Column 和 LazyColumn 的核心区别,各自适用场景?

参考答案:

Column一次性渲染全部子组件,适合少量固定布局内容;

LazyColumn懒加载,仅渲染屏幕可见条目,条目滑出屏幕回收,适合数量不确定、大量数据的滚动列表。

代码实操题

修改代码:给每一个待办项增加删除按钮,点击删除对应条目。参考答案

kotlin 复制代码
  
@Composable
fun ListDemoPage() {
    var inputText by remember { mutableStateOf("") }
    val todoList = remember { mutableStateListOf<String>() }

    Column(modifier = Modifier.padding(20.dp)) {
        TextField(
            value = inputText,
            onValueChange = { inputText = it },
            label = { Text("输入待办事项") }
        )
        Spacer(modifier = Modifier.height(12.dp))

        Button(onClick = {
            if(inputText.isNotBlank()){
                todoList.add(inputText)
                inputText = ""
            }
        }) {
            Text("添加待办")
        }
        Spacer(modifier = Modifier.height(16.dp))

        if(todoList.isEmpty()){
            Text("暂无待办,请添加任务")
        }else{
            LazyColumn {
                items(todoList){ item ->
                    Row(modifier = Modifier.padding(vertical = 4.dp)) {
                        Text("· $item")
                        Spacer(modifier = Modifier.width(10.dp))
                        Button(onClick = { todoList.remove(item) }) {
                            Text("删除")
                        }
                    }
                }
            }
        }
    }
}

答案与解析

解析:每行套Row横向布局,增加删除按钮;点击后调用 remove 删除列表元素,mutableStateListOf自动触发重组刷新列表。

五、本课小结

  1. if条件渲染:在可组合函数中直接分支渲染UI;
  2. LazyColumn:滚动懒加载列表,大数据优先选用;
  3. items 遍历集合生成列表项;
  4. 列表状态优先使用 mutableStateListOf ,增删自动触发重组。

下一课:rememberSaveable,页面旋转/系统重建保留状态。

相关推荐
墨天梦1 小时前
B19_SunnyWeather到阅读客户端
android·kotlin
敬往事一杯酒哈1 小时前
海康 AGV 导航读码器学习
学习
qq_284274053 小时前
机械原理笔记:平面机构自由度计算(复合铰链、局部自由度、虚约束)与四杆机构入门(含考点)
笔记·学习·平面·自动化·制造
qq_284274054 小时前
数控铣床与加工中心笔记:铣刀与刀柄系统、G54试切对刀、镜像加工指令、孔加工工艺(钻扩铰镗)与固定循环G73/G83/G81/G76/G87/G84
笔记·学习·自动化·制造
Titan20245 小时前
MySQL访问个人学习笔记
笔记·学习·mysql
小雪崩6 小时前
嵌入式学习 day64:字符设备驱动
学习
个 人 练 习 生6 小时前
C++ string 类模拟实现:从底层理解字符串(上)
开发语言·c++·经验分享·学习·程序人生
坤坤子吖7 小时前
C++智能指针:RAII、shared_ptr与内存泄漏
开发语言·c++·笔记·学习
词却8 小时前
OpenCV学习:MediaPipe 人脸网格检测
opencv·学习
李日华大战鸡红8 小时前
FOC SVPWM过调制(学习记录)
stm32·单片机·学习