鸿蒙5.0实战案例:基于WaterFlow的页面滑动加载

往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)

✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~

✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

✏️ 记录一场鸿蒙开发岗位面试经历~

✏️ 持续更新中……


场景描述

  • 场景一:瀑布流页面多列混排的布局场景,例如:10个item在2列内布局,中间5个item在1列内撑满宽度布局,后10个item在3列内布局。
  • 场景二:瀑布流页面中某一个Item可以固定展示在某一个位置,从而实现吸顶效果

方案描述

场景一:

waterFlow支持自定义Item,从而在WaterFlow内完成多列混排的自定义布局,同时懒加载保证性能。

方案

通过sections配置分组信息,并初始化瀑布流分组,通过splice替换/添加新分组。

核心代码

1、计算FlowItem宽/高,设置FlowItem的宽/高数组,通过对应Item,设置FlowItem的宽/高。

2、通过sections配置分组信息,并初始化瀑布流分组,具体根据 SectionOptions需要自定义。可通过Item和分组分组信息中itemsCount设置指定Item的布局,例如Item=5,第一个分组中itemsCount: 4,Item=5为第二个分组的第二个Item(此处Item从0开始)。

3、即将触底时提前增加数据,添加加新分组到瀑布流末尾。

//计算FlowItem宽/高

getSize() {

let ret = Math.floor(Math.random() * this.maxSize)

return (ret > this.minSize ? ret : this.minSize)

}

// 设置FlowItem的宽/高数组

setItemSizeArray() {

for (let i = 0; i < 100; i++) {

this.itemWidthArray.push(this.getSize())

this.itemHeightArray.push(this.getSize())

}

}

//配置分组信息,可通过Item和分组信息中itemsCount设置指定Item的布局,例如Item=5,第一个分组中为itemsCount: 4,Item=5为第二个分组的第二个Item(此处Item从0开始)

@State sections: WaterFlowSections = new WaterFlowSections()

oneColumnSection: SectionOptions = {

itemsCount: 4,//分组中FlowItem数量,必须是正整数。

crossCount: 1,//纵向布局时为列数,横向布局时为行数

columnsGap: 5,//该分组的列间距,不设置时使用瀑布流的columnsGap

rowsGap: 10,//该分组的行间距,不设置时使用瀑布流的rowsGap

margin: { top: 10, left: 5, bottom: 10, right: 5 },

onGetItemMainSizeByIndex: (index: number) => {//瀑布流组件布局过程中获取指定index的FlowItem的主轴大小

return 150

}

}

twoColumnSection: SectionOptions = {

itemsCount: 20,

crossCount: 2,

onGetItemMainSizeByIndex: (index: number) => {

return this.itemHeightArray[index 100]

}

}

//初始化分组信息

aboutToAppear() {

this.setItemSizeArray()

let sectionOptions: SectionOptions[] = []

let count = 0

let oneOrTwo = 0

while (count < this.dataCount) {

//当oneOrTwo为偶数时加载第一个分组,为奇数时加载第二个分组

if (oneOrTwo++ % 2 == 0) {

sectionOptions.push(this.oneColumnSection)

count += this.oneColumnSection.itemsCount

} else {

sectionOptions.push(this.twoColumnSection)

count += this.twoColumnSection.itemsCount

}

}

//splice(start: number, deleteCount?: number, sections?: Array<SectionOptions>)

//start为正数时,表示从瀑布流首位开始计算,到start位置时,splicet替换现有分组

//start为负数时,表示从瀑布流末尾开始,splicet添加新分组

//deleteCount 表示要从start开始删除的分组数量

this.sections.splice(-1, 0, sectionOptions)

}



//即将触底时提前增加数据

waterFlow({ scroller: this.scroller, sections: this.sections }) {

LazyForEach(this.dataSource, (item: number) => {

...

}

.onScrollIndex((first: number, last: number) => {

// 即将触底时提前增加数据

//剩最后二十条数据时,提前增加数据,设置新的分组信息,将新分组添加到瀑布流末尾

if (last + 20 >= this.dataSource.totalCount()) {

for (let i = 0; i < 100; i++) {

this.dataSource.addLastItem()

}

let newSection: SectionOptions = {

itemsCount: 100,

crossCount: 2,

onGetItemMainSizeByIndex: (index: number) => {

return this.itemHeightArray[index % 100]

}

}

this.sections.push(newSection)

}

})

场景二:

页面中某个Item跟随页面滑动,到达吸顶位置时,继续滑动,吸顶元素保持不动,其他元素继续滑动。

方案

在瀑布流分组中为要吸顶的部分预留出位置,监听瀑布流滚动事件,吸顶部分基于瀑布流滚动后的偏移量设置位置,让吸顶部分跟随瀑布流一起滚动,吸顶部分到顶后固定不动。

核心代码

1、在第一个分组中剔除Item=1,为吸顶部分留出位置,避免吸顶部分遮挡其余Item。

2、在数据渲染时也要剔除Item=1,其余Item正常渲染。

3、设置瀑布流的onWillScroll事件回调,监听瀑布流的滚动,吸顶部分基于瀑布流滚动后的偏移量设置位置,让吸顶部分跟随瀑布流一起滚动。吸顶部分初始位置为预留的Item=1的位置,吸顶部分到达顶部以后固定在顶部位置。

//预留吸顶部分位置

oneColumnSection: SectionOptions = {

itemsCount: 3,

crossCount: 1,

columnsGap: 5,

rowsGap: 10,

margin: { top: 10, left: 5, bottom: 10, right: 5 },

onGetItemMainSizeByIndex: (index: number) => {

if (index==1) {

return 100 //剔除Item=1,为吸顶部分留出位置

}else {

return 200

}

}

}

.....

WaterFlow({ scroller: this.scroller, sections: this.sections }) {

LazyForEach(this.dataSource, (item: number) => {

FlowItem() {

Column(){

//剔除Item=1,为吸顶部分留出位置

//可基于Item和分组数量设置指定Item的布局,例如Item=3为第二个分组的第一个Item(此处Item从0开始)

if (item!=1) {

Image('./Image/'+item%10 +'.png')

.objectFit(ImageFit.Cover)

.width("90%")

.height(100)

.layoutWeight(1)

.margin(5)

Text("必吃榜").fontSize(12).height('16')

}

}

}

.width('100%')

.height(this.itemHeightArray[item%100])

.backgroundColor(Color.White)

}, (item: string) => item)

}

.....

//onWillScroll瀑布流滑动前触发,返回当前帧将要滑动的偏移量和当前滑动状态。返回的偏移量为计算得到的将要滑动的偏移量值,并非最终实际滑动偏移。

//监听滚动事件,获取当前滚动偏移量和将要滚动的偏移量,scrollOffset保存滚动后的偏移量。

.onWillScroll((offset:number) => {

this.scrollOffset = this.scroller.currentOffset().yOffset + offset //currentOffset 当前滚动的偏移量

//未滚动时this.scrollOffset初始值为0

})

Stack() {

........

}.backgroundColor(Color.White)

}.alignItems(HorizontalAlign.Start)

}

.height(100)

.hitTestBehavior(HitTestMode.Transparent)

//this.scrollOffset滚动后的偏移量 滚动后的偏移量大于吸顶部分到顶部距离时,固定在顶部不动

//这里220为第一个Item高度200和第一个Item顶部和底部10的间隔

.position( {x: 0, y: this.scrollOffset >= 220 ? 0 : 220- this.scrollOffset })

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/978336.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

文件系统

目录 1.认识磁盘 磁盘的物理结构 CHS定位法 磁盘的逻辑结构 2.认识文件系统 inode 分区和分组 磁盘上的文件系统 3.软硬链接 软链接 软链接的操作 创建软链接 查看软链接 删除软链接 软链接的特点 软链接的使用场景 硬链接 硬链接的操作 创建硬链接 查看硬…

学习路之PHP --TP6异步执行功能 (无需安装任何框架)

学习路之PHP --异步执行功能 &#xff08;无需安装任何框架&#xff09; 简介一、工具类二、调用三、异步任务的操作四、效果&#xff1a; 简介 执行异步任务是一种很常见的需求&#xff0c;如批量发邮箱&#xff0c;短信等等执行耗时任务时&#xff0c;需要程序异步执行&…

一键部署DeepSeek

腾讯Cloud Studio提供DeepSeek一键部署功能&#xff0c;0行代码&#xff0c;秒级部署使用&#xff01; 重点是每月免费提供10000分钟&#xff01; 不用等待模型下载&#xff0c;创建即可使用。 内置 Ollama、DeepSeek-R1 1.5B、7B、8B、14B 及 32B 模型。 热门模板 AI模板 前…

(学习总结26)Linux工具:make/Makefile 自动化构建、Git 版本控制器 和 gdb/cgdb 调试器

Linux工具&#xff1a;make/Makefile 自动化构建、Git 版本控制器 和 gdb/cgdb 调试器 make/Makefile 自动化构建在 Linux 命令行中的命令 makeMakefile 的基本操作1. 编写与删文件基本操作2. 总是执行操作3. 执行操作时的依赖性4. 定义变量或命令操作与其它简单操作5. 多文件操…

Linux提权之docker提权(十三) 链接第八篇完整版

书接上回 实验环境一样的 第八篇 我们用ssh密钥登陆后 发现我们web1的权限 当我们拿到web1的权限时 我们无法提权(这里我用的继续十二的环境 大家也可以继续) 所以我们首先要提权(当然必须是一个完整的 tty shell 不会的 我们去看第二篇 当然我下边也给你表注明了) python3…

Docker启动ES容器打包本地镜像

文章目录 1、安装 Docker2、下载镜像3、查看已下载的镜像4、 保存和加载镜像5、.tar 文件与 Docker 镜像的关系6、如何从 .tar 文件加载 Docker 镜像7、为什么需要 .tar 文件&#xff1f;8、ES 8.x版本无法启动8.1 问题原因8.2 解决方案8.3 提交容器为新镜像 1、安装 Docker 如…

C#开发的Base64编码及解码完整源码及注意事项

在软件开发时&#xff0c;经常用Base64编码和解码功能。本文介绍一个简单易用的Base64 编码和解码工具&#xff0c;顾名思义&#xff0c;就是简单快捷地进行 Base64 代码的解码或编码操作。您的数据可以轻松地编码为 Base64 编码&#xff0c;也可以解码为可读的格式。传输数据时…

使用OpenCV实现帧间变化检测:基于轮廓的动态区域标注

在计算机视觉中&#xff0c;帧间差异检测&#xff08;frame differencing&#xff09;是一种常用的技术&#xff0c;用于检测视频流中的动态变化区域。这种方法尤其适用于监控、运动分析、目标追踪等场景。在这篇博客中&#xff0c;我们将通过分析一个基于OpenCV的简单帧间差异…

夜莺监控 - 边缘告警引擎架构详解

前言 夜莺类似 Grafana 可以接入多个数据源&#xff0c;查询数据源的数据做告警和展示。但是有些数据源所在的机房和中心机房之间网络链路不好&#xff0c;如果由 n9e 进程去周期性查询数据并判定告警&#xff0c;那在网络链路抖动或拥塞的时候&#xff0c;告警就不稳定了。所…

【QT 一 | 信号和槽】

Qt5基本模块 Qt Creator 中的快捷键 • 注释&#xff1a;ctrl / • 运⾏&#xff1a;ctrl R • 编译&#xff1a;ctrl B • 字体缩放&#xff1a;ctrl 鼠标滑轮 • 查找&#xff1a;ctrl F • 整行移动&#xff1a;ctrl shift ⬆/⬇ • 帮助⽂档&#xff1a;F1 • 自动…

Ubuntu本地使用AnythingLLM

1.介绍 AnythingLLM是一个全栈应用程序&#xff0c;由Mintplex Labs Inc.开发&#xff0c;旨在将任何文档、资源或内容片段转换为大语言模型&#xff08;LLM&#xff09;在聊天中可以利用的相关上下文。 2.在ubuntu本地安装 打开终端并运行&#xff1a; curl -fsSL https:/…

Rust学习总结之-枚举

枚举是一个很多语言都有的功能&#xff0c;不过不同语言中其功能各不相同但是要表达的意思是一致的&#xff0c;枚举就是对于一个事物可以穷举出所有可能得值。比如说人的性别就可以用枚举&#xff0c;男人和女人两种。下面我们来学习Rust中的枚举。 一&#xff1a;枚举定义 …

domain 网络安全 网络安全域

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 文章目录 1、域的概述 1.1、工作组与域1.2、域的特点1.3、域的组成1.4、域的部署概述1.5、活动目录1.6、组策略GPO 2、域的部署实验 2.1、建立局域网&#xf…

面试基础---深入解析 AQS

深入解析 AQS&#xff1a;从源码到实践&#xff0c;剖析 ReentrantLock 和 Semaphore 的实现 引言 在 Java 并发编程中&#xff0c;AbstractQueuedSynchronizer&#xff08;AQS&#xff09;是一个核心框架&#xff0c;它为构建锁和其他同步器提供了基础支持。ReentrantLock 和…

Harmony开发笔记(未完成)

一、感想 作为一名拥有11年经验的Android开发者&#xff0c;我亲历了Android从高速发展到如今面临“僧多粥少”的过程。技术的世界瞬息万变&#xff0c;没有一种技术能够让人依赖一辈子。去年初&#xff0c;我自学了鸿蒙系统&#xff0c;并顺利通过了鸿蒙官方的初级和高级认。…

计算机视觉(opencv-python)入门之常见图像处理基本操作(待补充)

图像预处理是计算机视觉任务中的关键步骤&#xff0c;它通过对原始图像进行处理&#xff0c;以提高后续图像分析、特征提取和识别的准确性。 示例图片 目录 常见图像预处理方法 灰度化处理 法一 法二 说明 切片截取部分图像数据 cv2.cvtColor() 颜色空间转换 cv2.spli…

设计模式Python版 备忘录模式

文章目录 前言一、备忘录模式二、备忘录模式示例1三、备忘录模式示例2 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a…

Linux红帽:RHCSA认证知识讲解(三)Linux基础指令与Vim编辑器的使用

Linux红帽&#xff1a;RHCSA认证知识讲解&#xff08;三&#xff09;Linux基础指令与Vim编辑器的使用 前言一、Linux基础指令二、Linux 文件系统层次结构概念三、通过路径指定文件四、使用命令行工具管理文件五、Vim 的安装方式六、Vim 的操作模式七、红帽建议掌握的 Vim 键和命…

auto.js例子之WebView多页面浏览器

"ui";ui.layout(<vertical><horizontal id"webs" layout_weight"1"></horizontal><button id"one" text"第一个" /><button id"two" text"第二个" /><button id"…