【鸿蒙实战开发】基于WaterFlow的页面滑动加载

108 篇文章 0 订阅
70 篇文章 0 订阅

往期知识点整理

场景描述

场景一:瀑布流页面多列混排的布局场景,例如: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 })

总是有很多小伙伴反馈说:鸿蒙开发不知道学习哪些技术?不知道需要重点掌握哪些鸿蒙开发知识点? 为了解决大家这些学习烦恼。在这准备了一份很实用的鸿蒙全栈开发学习路线与学习文档给大家用来跟着学习。

针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植……等)技术知识点。

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

鸿蒙开发面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN/733GH/overview

在这里插入图片描述

OpenHarmony 开发环境搭建

图片

《OpenHarmony源码解析》:https://gitcode.com/HarmonyOS_MN/733GH/overview

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview

图片

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值