【鸿蒙原生开发】自定义实现refresh组件的下拉样式

一:前言

根据研究机构Counterpoint Research发布的最新数据,2024年第一季度,鸿蒙OS份额由去年一季度的8%上涨至17%,iOS份额则从20%下降至16%。这意味着,华为鸿蒙OS在中国市场的份额超越苹果iOS,已成中国第二大操作系统。

随着鸿蒙市场份额的不断提升,相应的岗位也会迎来一个爆发式的增长。这对于想要换赛道的程序员来说是一个非常好的消息,话说大家最近有想法转型鸿蒙开发吗?

有群友在提问的时候问到了下拉刷新的样式怎么更改,刚好我又做过了这个功能,然后写一篇文章来总结一下

二:核心原理

在HarmonyOS开发中,实现自定义下拉刷新样式的关键在于使用Refresh组件。该组件支持传入一个自定义的builder,用于定义下拉刷新时的显示内容。通过利用状态变量和构建器方法,可以动态地控制和更新刷新状态的显示内容。

三:思路

●定义状态变量:

○refreshIng: 控制下拉刷新状态。
○refreshStatus: 控制刷新状态文本。
○loading 和 finished: 控制底部加载状态。

●创建刷新状态文本生成方法:

○getStatusText(): 根据不同的刷新状态返回相应的文本,如“继续下拉”、“松手加载”、“加载中”等。

●创建自定义刷新显示内容的构建器方法:

○getRefreshDisPlay(): 使用Row布局,包含进度条和状态文本,根据当前的刷新状态动态更新显示内容。

●实现主构建方法:

○使用Refresh组件,传入refreshing状态和builder方法。
○使用List组件渲染数据项和底部加载内容。
○处理onReachEnd事件,实现上拉加载功能。
○处理onStateChange事件,实现下拉刷新功能,更新刷新状态和显示内容。

四:核心api

●Refresh组件:

○用于实现下拉刷新功能,支持传入refreshing状态和自定义的builder方法。
○refreshing: 控制刷新状态。
○builder: 自定义刷新时的显示内容。

●LoadingProgress组件:

○显示加载进度条。
○color, width, height: 设置进度条的颜色和尺寸。

●Text组件:

○显示文本内容。
○fontColor, fontSize: 设置文本的颜色和字体大小。

●@Builder getRefreshDisPlay() : 这是一个构建器函数,用来生成自定义的刷新显示内容。

○使用Row布局,设置间距为10。
○显示加载进度条,并设置颜色和尺寸。
○显示由getStatusText函数返回的刷新状态文本。

●@Builder getRefreshDisPlay() : 这是一个构建器函数,用来生成自定义的刷新显示内容。

○使用Row布局,设置间距为10。
○显示加载进度条,并设置颜色和尺寸。
○显示由getStatusText函数返回的刷新状态文本。

五:代码举例(关键地方都给了注释)

@Component
struct HmList {
 @State
 refreshIng: boolean = false // 控制下拉刷新的变量
 // 传入数据的数组 根据数组进行渲染
 @Prop
 dataSource: object[] = [] // 数据源
 // 上拉加载的方法
 onLoad: () => void = () => {
 } // 由调用者传入
 // 下拉刷新方法
 onRefresh: () => void = () => {
 } // 下拉刷新的方法
 // 需要一个标记 还没有数据的标记
 @Prop
 finished: boolean = false // 是否还有下一页数据
 @State
 loading: boolean = false // 是否正在加载中 1.显示加载中文本 2. 用来做阀门 当前这次请求没结束之前 下次请求滚远点
 loadingText: string = "加载中.." // 加载中的文本
 finishText: string = "没有数据啦" // 所有数据加载完成的文本
 @BuilderParam
 renderItem: (item: object) => void // 由调用者传入 由HmList调用 传入每一个项的数据
 @State
 refreshStatus: RefreshStatus = RefreshStatus.Inactive

 @Builder
 getBottomDisplay() {
   // 获取底部的展示内容
   Row({ space: 10 }) {
     if (this.finished) {
       // 此时应该没有动画的loading
       Text(this.finishText)
         .fontSize(14)
         .fontColor($r('app.color.text_secondary'))
     } else {
       Text(this.loadingText)
         .fontSize(14)
         .fontColor($r('app.color.text_secondary'))
       LoadingProgress()
         .width(20)
         .aspectRatio(1)
         .color($r('app.color.text_secondary'))
     }
   }
   .width('100%')
   .height(50)
   .justifyContent(FlexAlign.Center)
 }

 // 动态生产文本
 getStatusText() {
   switch (this.refreshStatus) {
     case RefreshStatus.Inactive:
       return ''
     case RefreshStatus.Drag:
       return '继续下拉'
     case RefreshStatus.OverDrag:
       return '松手加载'
     case RefreshStatus.Refresh:
       return '加载中'
   }
   return ''
 }

 @Builder
 getRefreshDisPlay() {
   Row({ space: 10 }) {
     LoadingProgress()
       .color($r('app.color.primary'))
       .width(40)
       .height(40)
     Text(this.getStatusText())
       .fontColor($r('app.color.text_secondary'))
       .fontSize(14)
   }
   .justifyContent(FlexAlign.Center)
   .height(50)
   .width("100%")
 }

 build() {
   // Refresh组件支持传入一个自定义的builder来定义刷新时的显示内容
   Refresh({ refreshing: $$this.refreshIng ,builder :this.getRefreshDisPlay()}) {
     List() {
       ForEach(this.dataSource, (item: object) => {
         // 每一项的结构的UI内容不是由列表决定 而由使用者决定
         // 传入builderParam if确保 renderItem 是一个有效的函数。
         if (this.renderItem) {
           this.renderItem(item)
         }
       })
       // 最后放置文本的地方
       ListItem() {
         this.getBottomDisplay()
       }
     }
     .onReachEnd(async () => {
       // 实现上拉加载
       // 需要一个标记 是否已经加载完所有数据
       // 在没有加载完所有页数据的情况 且没有请求在进程中的情况下
       if (!this.finished && !this.loading) {
         this.loading = true // 关闭阀门
         await this.onLoad() //实现上拉加载
         this.loading = false // 打开阀门
       }
     })
   }
   .onStateChange(async (State) => {
     // 实现下拉刷新
     this.refreshStatus = State
     if (State === RefreshStatus.Refresh) {
       // 松手加载
       await this.onRefresh() // 调用刷新方法
       this.refreshIng = false // 关闭下拉的动画效果
       this.loading = false // 关闭上拉刷新的loading
       // 下拉刷新意味着所有数据全都不要 重新来过
     }
   })
 }
}

export { HmList }

六 : 效果动态图

七:总结

关键在于利用Refresh组件和其builder属性,自定义刷新时的显示内容。同时,结合状态变量和构建器方法,可以动态更新刷新状态,显示不同的提示文本和加载动画。希望通过这个总结,能帮助你更好地理解和应用这些核心API和实现步骤。

写在最后

有很多小伙伴不知道该从哪里开始学习鸿蒙开发技术?也不知道鸿蒙开发的知识点重点掌握的又有哪些?自学时频繁踩坑,导致浪费大量时间。结果还是一知半解。所以有一份实用的鸿蒙(HarmonyOS NEXT)全栈开发资料用来跟着学习是非常有必要的。

获取完整版高清学习资料,请点击→鸿蒙全栈开发学习资料(安全链接,请放心点击)

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了

最新鸿蒙全栈开发学习线路在这里插入图片描述

鸿蒙HarmonyOS开发教学视频

在这里插入图片描述
在这里插入图片描述

大厂面试真题

在这里插入图片描述

在这里插入图片描述

鸿蒙OpenHarmony源码剖析

在这里插入图片描述

这份资料能帮住各位小伙伴理清自己的学习思路,更加快捷有效的掌握鸿蒙开发的各种知识。有需要的小伙伴自行领取,,先到先得~无套路领取!!

获取这份完整版高清学习资料,请点击→鸿蒙全栈开发学习资料(安全链接,请放心点击)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值