
前言本节课学习 LazyRow 横向懒加载滚动列表并且结合TextField输入框实现列表搜索过滤实战。复习Lazy系列懒加载DSL、remember状态练习数据源过滤。知识点清单LazyRow横向懒加载滚动列表对比LazyColumn纵向列表item{}、items{}、itemsIndexed{} 在LazyRow中的用法TextField文本输入维护搜索关键字状态Kotlin集合filter()过滤数据源实现实时搜索过滤之后渲染懒加载列表状态驱动页面更新完整示例源码ComposablefunLazyRowSearchDemoPage(){//原始完整数据源valoriginDatalistOf(Java,Kotlin,Dart,Rust,Go,C,C#,Swift,Cangjie,Python)//保存搜索框输入文本varsearchKeywordbyremember{mutableStateOf()}// 根据关键字实时过滤数据源valfilterResultremember(searchKeyword){originData.filter{item-item.contains(searchKeyword,ignoreCasetrue)}}Column(modifierModifier.fillMaxSize().padding(20.dp),verticalArrangementArrangement.spacedBy(16.dp)){TextField(valuesearchKeyword,onValueChange{searchKeywordit},placeholder{Text(请输入搜索语言名称)},modifierModifier.fillMaxWidth())Text(text横向热门语言LazyRow,fontSize18.sp,fontWeightFontWeight.Medium)LazyRow(horizontalArrangementArrangement.spacedBy(12.dp)){items(filterResult){name-Card(modifierModifier.height(80.dp),elevationCardDefaults.cardElevation(4.dp)){Text(textname,modifierModifier.padding(horizontal16.dp).wrapContentHeight(Alignment.CenterVertically),fontSize17.sp)}}}Text(text纵向过滤结果LazyColumn,fontSize18.sp,fontWeightFontWeight.Medium)LazyColumn(modifierModifier.weight(1f).fillMaxWidth(),verticalArrangementArrangement.spacedBy(10.dp)){items(filterResult){name-Card(modifierModifier.fillMaxWidth()){Text(textname,modifierModifier.padding(14.dp),fontSize17.sp)}}}}}逐行解读LazyRow横向懒加载LazyRow水平方向滚动的懒加载容器对应LazyColumn垂直滚动。DSL语法和LazyColumn完全一样支持 item{} 、 items{} 、 itemsIndexed{} 。horizontalArrangement.spacedBy(12.dp) 设置横向条目之间的间距。remember(key){ } 带依赖key的记忆remember(searchKeyword) 当searchKeyword发生变化的时候会重新执行大括号内的过滤逻辑searchKeyword不变的时候直接复用上一次过滤结果避免不必要重复计算。filter集合过滤 ignoreCase truecontains(searchKeyword, ignoreCase true) 忽略大小写匹配输入小写也可以匹配大写的文本。Modifier.weight(1f)LazyColumn设置weight(1f)在Column垂直布局里面占掉剩余屏幕高度防止列表挤压上面搜索框与横向LazyRow。容易踩坑❌ LazyRow内部同样必须使用item / items DSL不可以直接写组件。❌ 过滤数据源一定要写remember(依赖关键字)否则每次重组都会反复执行filter造成不必要计算。❌ 在Column里面直接给LazyColumn写fillMaxSize会布局异常使用 weight(1f) 分配剩余高度。✅ 搜索过滤不要修改原始集合基于原始数据源filter得到新的过滤后集合。多元化习题每道题后紧跟答案解读习题1【基础‑改错题】题目找出下面LazyRow代码错误并修复LazyRow(){Card(){Text(测试1)}Card(){Text(测试2)}}答案LazyRow(){items(listOf(测试1,测试2)){str-Card(){Text(str)}}}解读LazyRow属于懒加载DSL域不能直接放置CardUI条目必须包裹在item{}或者items{}内部语法规则与LazyColumn完全一致。习题2【基础‑代码修改题】题目在示例横向LazyRow的最前面增加一个头部卡片文本【热门】只显示一次。答案LazyRow(horizontalArrangementArrangement.spacedBy(12.dp)){item{Card(elevationCardDefaults.cardElevation(4.dp)){Text(热门,modifierModifier.padding(16.dp).wrapContentHeight(Alignment.CenterVertically),fontSize17.sp)}}items(filterResult){name-Card(modifierModifier.height(80.dp),elevationCardDefaults.cardElevation(4.dp)){Text(textname,modifierModifier.padding(horizontal16.dp).wrapContentHeight(Alignment.CenterVertically),fontSize17.sp)}}}解读横向列表的头部依然使用 item{} 单独渲染item块渲染单个元素不参与循环放在items前面。LazyRow和LazyColumn的DSL接口完全统一。习题3【进阶‑补充代码题】题目当filterResult过滤之后结果为空没有搜索匹配项纵向LazyColumn上方显示提示文本“未查询到匹配数据”。写出该item片段。答案LazyColumn(modifierModifier.weight(1f).fillMaxWidth(),verticalArrangementArrangement.spacedBy(10.dp)){if(filterResult.isEmpty()){item{Text(未查询到匹配数据,modifierModifier.padding(20.dp),fontSize18.sp,colorColor.Gray)}}items(filterResult){name-Card(modifierModifier.fillMaxWidth()){Text(textname,modifierModifier.padding(14.dp),fontSize17.sp)}}}解读可以直接在Lazy的DSL里面写if分支当过滤后的集合为空的时候渲染提示item有数据就直接渲染items条目实现空状态提示。习题4【综合‑逻辑应用题】题目改造搜索逻辑要求搜索的时候区分大小写不再忽略大小写同时如果搜索关键字为空字符串纵向列表只展示前5条数据。书写remember过滤块代码。答案valfilterResultremember(searchKeyword){if(searchKeyword.isEmpty()){originData.take(5)}else{originData.filter{item-item.contains(searchKeyword)}}}解读去掉 ignoreCasetrue 之后contains就严格区分大小写take(5)截取集合前5个元素利用remember(searchKeyword)绑定关键字作为依赖关键字变化重新执行筛选逻辑。习题5【概念简答题】题目LazyRow与LazyColumn异同是什么答案相同点都属于懒加载组件拥有视图复用DSL语法item、items、itemsIndexed完全一致。不同点LazyRow是水平方向滚动LazyColumn是垂直方向滚动布局方向不一样间距属性一个horizontalArrangement一个verticalArrangement。解读LazyRow适合横向滑动的标签、分类LazyColumn适合长垂直数据列表开发的时候根据产品UI滚动方向选型。本节课知识点总结LazyRow横向懒加载滚动列表和LazyColumn一样具备条目复用适合横向滑动展示标签、分类。LazyRow与LazyColumn共享同一套DSL语法item{}单独条目items{}循环渲染。remember(key){ } 可以添加状态依赖当key对应的值改变块内逻辑重新运算用于数据源过滤。搜索过滤业务原则保留原始数据源基于原始集合filter生成过滤结果集合不要修改原集合。在Column嵌套LazyColumn的时候LazyColumn优先使用 Modifier.weight(1f) 来分配剩余可用高度避免布局报错。下一课预告第16课 Scaffold脚手架、TopAppBar顶部导航栏实战