HarmonyOS 应用开发《掌上英语》第76篇:LazyVWaterFlowLayout 瀑布流:错题本与收藏夹的高效展示方案
LazyVWaterFlowLayout 瀑布流错题本与收藏夹的高效展示方案一、瀑布流 vs Grid何时选择谁在 HarmonyOS 5.0 中列表和网格布局主要依靠List和Grid两个容器组件。它们适用于内容高度一致的场景——比如我们的CourseHomePage单词卡片列表每个卡片高度相同用 Grid 整齐排列非常合适。但在一些场景中内容的高度天然不统一。例如MyWrongPage错题本有的错题是单词拼写只显示单词和音标内容很短有的错题是阅读理解包含题目原文、选项、用户的错误答案和正确答案内容很长。如果使用 Grid 布局所有 item 的高度必须对齐到最长的那一个导致短内容周围出现大量空白视觉上不均匀。HarmonyOS 6.0 新增的LazyVWaterFlowLayout懒加载瀑布流布局正是为这种场景设计的。与 Grid 不同瀑布流允许每个 item 独立确定高度按列依次排列短的 item 后面紧跟下一个 item形成水流般的紧凑布局。对比维度Grid 网格布局LazyVWaterFlowLayout 瀑布流内容高度要求统一允许不同布局密度有空白间隙紧凑排列适用场景单词卡片、图标入口错题本、收藏夹、笔记滚动性能优秀优秀懒加载item 复用支持支持二、LazyVWaterFlowLayout API 与使用限制LazyVWaterFlowLayout的基本使用方式如下LazyVWaterFlowLayout({ dataSource: this.wrongQuestionDataSource,columns:2,columnsGap:12,rowsGap:12,itemWidth:auto,itemHeight:auto,layoutWeight:1, }) {// item 渲染}关键参数说明dataSource数据源需要实现IDataSource接口支持懒加载。columns列数可以是固定值也可以根据 ContainerReader 动态调整。columnsGap / rowsGap列间距和行间距。itemWidth / itemHeight设置为 auto 时由内容决定尺寸。使用限制方面需要注意以下几点必须嵌套在可滚动容器内LazyVWaterFlowLayout本身不能独立滚动需要放置在Scroll组件内部。不支持跨列合并与 CSS 瀑布流不同不支持一个 item 跨多列。item 高度必须在渲染时确定不支持异步加载内容后动态改变高度但可以用占位符预先占位。数据源增删时整体刷新与LazyForEach的增量更新不同瀑布流数据源目前只支持全量刷新。三、按需加载与 item 复用性能优势LazyVWaterFlowLayout的命名前缀 Lazy 已经揭示了它的核心设计理念——懒加载。它只渲染当前可见区域内的 item以及上下各预加载若干 item预加载数量可通过cachedCount参数配置。当用户滚动时离开可见区域的 item 会被回收进入可见区域的新 item 会被创建。在复用方面LazyVWaterFlowLayout支持Reusable装饰器复用机制与 List/Grid 一致。结合文章 79 会详细介绍的ReusableV2全局复用池瀑布流中的卡片组件可以跨列表复用进一步减少创建开销。对于 500 词的错题本场景假设用户错了 150 题在 Grid 布局中需要一次性创建 150 个 item 对象即使只有 10 个在屏幕上。而在瀑布流中只需要创建约 15-20 个 item屏幕可见 预加载内存占用减少 80% 以上。四、MyWrongPage 错题展示改造MyWrongPage是错题本页面包含MyWrongItem组件展示用户的错题列表。现有的实现使用List组件垂直排列每个错题占据一个完整的行宽。在宽屏设备上这种布局效率很低——左右两侧大量空白而每个错题内容长度又不同。使用LazyVWaterFlowLayout改造后错题卡片以瀑布流排列LocalwaterFlowColumns:number2;build() {Column() {TopBar({title:错题本});ContainerReader({onContainerChange:(width:number) {this.waterFlowColumns width 500?3:2; }}) {Scroll() {LazyVWaterFlowLayout({dataSource:this.wrongDataSource,columns:this.waterFlowColumns,columnsGap:12,rowsGap:12, }) {// 复用已有的 MyWrongItem 组件} } .scrollable(ScrollDirection.Vertical); } .layoutWeight(1); } .width(100%) .height(100%); }每个错题卡片的内容高度由其自身内容决定一个只有 2 行文本的简单错题占用很小的空间而包含题目原文、选项分析的复杂错题占用更多空间。瀑布流将这些不同高度的卡片紧凑排列在相同屏幕空间内展示更多内容。在改造时需要注意MyWrongItem组件本身不需要修改——它自带的高度自适应特性通过Column包裹内容天然适合瀑布流。只需要将外部容器从List改为Scroll LazyVWaterFlowLayout即可。五、MyCollectionPage 收藏展示的混合布局MyCollectionPage收藏页面展示用户收藏的单词和笔记。与错题本类似收藏内容的高度也不统一——有的收藏只是一个单词短内容有的收藏包含单词 用户笔记 标签长内容。更特别的是收藏页面可以包含两种类型的 item单词卡片和笔记卡片。瀑布流天然支持不同类型 item 混合排列因为每个 item 独立渲染LazyVWaterFlowLayout({dataSource:this.collectionDataSource,columns:2,columnsGap:12,rowsGap:12,}){// 类型1单词卡片MyCollectionItem({item: collectionItem});// 类型2笔记卡片高度通常比单词卡片大NoteCard({note: collectionItem.note});}混合布局中不同高度和不同类型的卡片交错排列形成丰富的视觉节奏。短的单词卡片旁边可能是一张长的笔记卡片视觉上错落有致比整齐划一的 Grid 布局更有浏览的趣味性。六、实践建议高度不一致时用瀑布流在我们的英语学习 App 中需要根据内容特征选择布局方式适用瀑布流的场景错题本MyWrongPage错误类型多样内容长度差异大。收藏夹MyCollectionPage单词 笔记混合高度不一致。首页猜你喜欢推荐区每个推荐单词的描述长度不同。保持 Grid 的场景单词卡片列表CourseHomePage的卡片切换模式每张卡片高度一致。功能入口图标MainPage的 5 个功能入口高度完全一致。分类筛选 Tab固定高度无需瀑布流。选择标准很简单如果列表中的 item 高度差异超过 2 倍优先考虑瀑布流如果所有 item 高度基本相同使用 Grid。七、总结LazyVWaterFlowLayout瀑布流为内容高度不统一的列表场景提供了高效的布局方案。在MyWrongPage和MyCollectionPage中瀑布流不仅减少了空白空间、增加了信息密度还因为懒加载特性降低了内存占用。结合 ContainerReader 实现列数自适应以及 Reusable 复用机制瀑布流在大规模内容列表场景中兼具美观和性能优势。

相关新闻

HarmonyOS 应用开发《掌上英语》第75篇:ContainerReader 容器断点:告别全局 BreakpointModel,实现组件级自适应布局

HarmonyOS 应用开发《掌上英语》第75篇:ContainerReader 容器断点:告别全局 BreakpointModel,实现组件级自适应布局

ContainerReader 容器断点:告别全局 BreakpointModel,实现组件级自适应布局一、为什么需要容器断点 在 HarmonyOS 5.0 时代,实现多设备适配主要依赖全局断点方案——通过 BreakpointModel 监听窗口尺寸变化,将设备分为 sm/md/lg 三…

2026/10/14 23:41:17 阅读更多 →
分支限界法精解:高效求解最小权顶点覆盖问题

分支限界法精解:高效求解最小权顶点覆盖问题

1. 问题引入:从一道经典面试题说起最近在帮团队面试算法工程师时,我总会抛出一个问题:“给你一个无向图,每个顶点都有一个正权重,如何找到一个顶点集合,使得图中的每条边至少有一个端点在这个集合里&#x…

2026/10/14 23:41:21 阅读更多 →
深入解析CAN接口:从差分信号到多主仲裁的嵌入式通信实战

深入解析CAN接口:从差分信号到多主仲裁的嵌入式通信实战

1. 项目概述:从“车内局域网”到工业神经如果你拆开过一辆现代汽车的仪表台,或者观察过一台自动化产线的控制柜,里面密密麻麻的线束可能会让你头皮发麻。但正是这些线束,构成了设备内部各个“器官”之间高速、可靠的通信网络。而C…

2026/10/14 23:41:26 阅读更多 →

最新新闻

双电机项目的学习记录1

双电机项目的学习记录1

cubemx里的配置问题,为什么这样配System Core → RCC → High Speed Clock (HSE) 选 Crystal/Ceramic Resonator所以才这样配置是为了精度更高-----------------------------------------------------------------------------------------------------------------…

2026/10/15 4:04:46 阅读更多 →
page_alloc alloc_pages_exact_noprof

page_alloc alloc_pages_exact_noprof

alloc_pages_exact_noprof() 是 alloc_pages_exact() 的无 profiling 底层实现,核心目标是分配“恰好满足需求”的物理连续内存,而非伙伴系统默认的 2 的幂次页块。设计动机:消除高阶分配的浪费伙伴系统只能按 2^order 个页分配。如果你需要 …

2026/10/15 4:04:46 阅读更多 →
SAP ABAP DDIC Table Type 深度解析,从 Internal Table 类型蓝图到主键、辅助键与 Clean Core

SAP ABAP DDIC Table Type 深度解析,从 Internal Table 类型蓝图到主键、辅助键与 Clean Core

在一个规模稍大的 SAP ABAP 项目里,经常会看到这样的声明。 DATA lt_flights TYPE spfli_key_tab.代码只有一行,但这里其实已经确定了很多东西。lt_flights 的每一行长什么样,它到底是 STANDARD TABLE、SORTED TABLE 还是 HASHED TABLE,哪些字段组成主键,主键是否允许重复…

2026/10/15 4:04:46 阅读更多 →
page_alloc alloc_pages_exact_nid_noprof

page_alloc alloc_pages_exact_nid_noprof

alloc_pages_exact_nid_noprof() 是 alloc_pages_exact() 的 NUMA 节点限定版本,并在 noprof重构中被引入。核心作用与设计动机它的核心目标是:在指定 NUMA 节点上优先分配“恰好满足需求”的物理连续内存。与 alloc_pages_exact_noprof() 的关键区别在于…

2026/10/15 4:04:46 阅读更多 →
为什么很多人的经验无法长期积累?

为什么很多人的经验无法长期积累?

记忆留不住的客观规律很多人觉得经验攒不下来是自己不用心,其实大脑本身就不擅长长期存储高密度的细节信息。认知心理学的追踪数据显示,人对具体场景下的信息细节,72小时后的自然留存率仅为29%,剩下的内容会被大脑自动修剪成模糊的…

2026/10/15 4:04:46 阅读更多 →
Map 中删除一个 key,它的内存会释放么?

Map 中删除一个 key,它的内存会释放么?

在 Go 语言开发中,我们频繁使用内置函数 delete(m, key) 来删除哈希表中的元素。许多开发者直觉上会认为:既然删除了 key,对应的内存就应该被操作系统或 Go 垃圾回收器(GC)回收。然而事实并非如此:调用 del…

2026/10/15 4:03:46 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →