首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

HarmonyOS开发实战( Beta5版)WaterFlow高性能开发实践

  • 25-03-03 06:42
  • 2415
  • 8575
blog.csdn.net

背景

瀑布流常用于展示图片信息,如多用于购物、资讯类应用。下面通过对WaterFlow组件示例代码的逐步改造,介绍优化WaterFlow性能的方法。

使用懒加载

先看一下组件示例代码中瀑布流的基本用法:

  1. build() {
  2. Column({ space: 2 }) {
  3. WaterFlow() {
  4. LazyForEach(this.datasource, (item: number) => {
  5. FlowItem() {
  6. Column() {
  7. Text("N" + item).fontSize(12).height('16')
  8. Image('res/waterFlowTest (' + item % 5 + ').jpg')
  9. .objectFit(ImageFit.Fill)
  10. .width('100%')
  11. .layoutWeight(1)
  12. }
  13. }
  14. .width('100%')
  15. // 提前设定FlowItem高度,避免自适应图片高度
  16. .height(this.itemHeightArray[item])
  17. .backgroundColor(this.colors[item % 5])
  18. }, (item: string) => item)
  19. }
  20. .columnsTemplate("1fr 1fr")
  21. .columnsGap(10)
  22. .rowsGap(5)
  23. .backgroundColor(0xFAEEE0)
  24. .width('100%')
  25. .height('80%')
  26. }
  27. }

示例代码已经使用了LazyForEach进行数据懒加载,WaterFlow布局时会根据可视区域按需创建FlowItem组件,并在FlowItem滑出可视区域外时销毁以降低内存占用。

另外,由于Image组件默认异步加载,建议提前根据图片大小设定FlowItem的高度,避免图片加载成功后高度变化触发瀑布流刷新布局。GitCode - 全球开发者的开源社区,开源代码托管平台

无限滚动

示例代码中FlowItem数量是固定的,不能满足无限滚动的场景。

基于WaterFlow本身提供的能力,可以在onReachEnd时给LazyForEach数据源增加新数据,并将footer做成正在加载新数据的样式(使用LoadingProgress组件)。

  1. build() {
  2. Column({ space: 2 }) {
  3. WaterFlow({ footer: this.itemFoot.bind(this) }) {
  4. LazyForEach(this.datasource, (item: number) => {
  5. FlowItem() {
  6. Column() {
  7. Text("N" + item).fontSize(12).height('16')
  8. Image('res/waterFlowTest (' + item % 5 + ').jpg')
  9. .objectFit(ImageFit.Fill)
  10. .width('100%')
  11. .layoutWeight(1)
  12. }
  13. }
  14. .width('100%')
  15. .height(this.itemHeightArray[item % 100])
  16. .backgroundColor(this.colors[item % 5])
  17. }, (item: string) => item)
  18. }
  19. // 触底加载数据
  20. .onReachEnd(() => {
  21. console.info("onReachEnd")
  22. setTimeout(() => {
  23. for (let i = 0; i < 100; i++) {
  24. this.datasource.AddLastItem()
  25. }
  26. }, 1000)
  27. })
  28. .columnsTemplate("1fr 1fr")
  29. .columnsGap(10)
  30. .rowsGap(5)
  31. .backgroundColor(0xFAEEE0)
  32. .width('100%')
  33. .height('80%')
  34. }
  35. }
  36. // 在数据尾部增加一个元素
  37. public AddLastItem(): void {
  38. this.dataArray.splice(this.dataArray.length, 0, this.dataArray.length)
  39. this.notifyDataAdd(this.dataArray.length - 1)
  40. }

此处需要通过在尾部增加元素的方式新增数据,不能使用直接修改dataArray后通过LazyForEach的onDataReloaded()通知瀑布流重新加载数据。

由于瀑布流布局子组件高度不相等的特点,下面节点的位置依赖上面的节点,重新加载所有数据会触发整个瀑布流重新计算布局导致卡顿。而在数据末尾增加数据后使用notifyDataAdd(this.dataArray.length - 1)通知,瀑布流就知道有新增数据可以继续加载,同时又不会重复处理已有数据。

提前新增数据

虽然在onReachEnd()触发时新增数据可以实现无限加载,但在滑动到底部时,会有明显的停顿加载新数据的过程。

想要流畅的进行无限滑动,还需要调整下增加新数据的时机。比如可以在LazyForEach还剩若干个数据就迭代到结束的情况下提前增加一些新数据。

  1. build() {
  2. Column({ space: 2 }) {
  3. WaterFlow() {
  4. LazyForEach(this.datasource, (item: number) => {
  5. FlowItem() {
  6. Column() {
  7. Text("N" + item).fontSize(12).height('16')
  8. Image('res/waterFlowTest (' + item % 5 + ').jpg')
  9. .objectFit(ImageFit.Fill)
  10. .width('100%')
  11. .layoutWeight(1)
  12. }
  13. }
  14. .onAppear(() => {
  15. // 即将触底时提前增加数据
  16. if (item + 20 == this.datasource.totalCount()) {
  17. for (let i = 0; i < 100; i++) {
  18. this.datasource.AddLastItem()
  19. }
  20. }
  21. })
  22. .width('100%')
  23. .height(this.itemHeightArray[item % 100])
  24. .backgroundColor(this.colors[item % 5])
  25. }, (item: string) => item)
  26. }
  27. .columnsTemplate("1fr 1fr")
  28. .columnsGap(10)
  29. .rowsGap(5)
  30. .backgroundColor(0xFAEEE0)
  31. .width('100%')
  32. .height('80%')
  33. }
  34. }

此处通过在FlowItem的onAppear中判断距离数据终点的数量,提前增加数据的方式实现了无停顿的无限滚动。

组件复用

现在,得到了一个无限滚动且没有显式等待加载的瀑布流,还能不能进一步优化性能呢?

考虑到滑动场景存在FlowItem及其子组件的频繁创建和销毁,可以将FlowItem中的组件封装成自定义组件,并使用@Reusable装饰器修饰,使其具备组件复用能力,减少ArkUI框架内部反复创建销毁节点的开销。组件复用的详细介绍可以参考组件复用最佳实践。

  1. build() {
  2. Column({ space: 2 }) {
  3. WaterFlow() {
  4. LazyForEach(this.datasource, (item: number) => {
  5. FlowItem() {
  6. // 使用可复用自定义组件
  7. ReusableFlowItem({ item: item })
  8. }
  9. .onAppear(() => {
  10. // 即将触底时提前增加数据
  11. if (item + 20 == this.datasource.totalCount()) {
  12. for (let i = 0; i < 100; i++) {
  13. this.datasource.AddLastItem()
  14. }
  15. }
  16. })
  17. .width('100%')
  18. .height(this.itemHeightArray[item % 100])
  19. .backgroundColor(this.colors[item % 5])
  20. }, (item: string) => item)
  21. }
  22. .columnsTemplate("1fr 1fr")
  23. .columnsGap(10)
  24. .rowsGap(5)
  25. .backgroundColor(0xFAEEE0)
  26. .width('100%')
  27. .height('80%')
  28. }
  29. }
  30. @Reusable
  31. @Component
  32. struct ReusableFlowItem {
  33. @State item: number = 0
  34. // 从复用缓存中加入到组件树之前调用,可在此处更新组件的状态变量以展示正确的内容
  35. aboutToReuse(params) {
  36. this.item = params.item;
  37. }
  38. build() {
  39. Column() {
  40. Text("N" + this.item).fontSize(12).height('16')
  41. Image('res/waterFlowTest (' + this.item % 5 + ').jpg')
  42. .objectFit(ImageFit.Fill)
  43. .width('100%')
  44. .layoutWeight(1)
  45. }
  46. }
  47. }

总结

WaterFlow配合LazyForEach渲染控制语法、提前加载数据和组件复用可以达到无限滚动场景性能最优效果。

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为资料太多,太杂,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。 

为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:

GitCode - 全球开发者的开源社区,开源代码托管平台  希望这一份鸿蒙学习文档能够给大家带来帮助~


鸿蒙(HarmonyOS NEXT)最新学习路线

​

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频学习教程+学习PDF文档

HarmonyOS Next 最新全套视频教程

  纯血版鸿蒙全套学习文档(面试、文档、全套视频等)       

​​

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

文章知识点与官方知识档案匹配,可进一步学习相关知识
CS入门技能树Linux入门初识Linux42834 人正在系统学习中
注:本文转载自blog.csdn.net的让开,我要吃人了的文章"https://blog.csdn.net/weixin_55362248/article/details/141864646"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top