HarmonyOS开发:开源一个刷新加载组件

前言

系统Api中提供了下拉刷新组件Refresh,使用起来也是非常的好用,但是风格和日常的开发,有着巨大的出入,效果如下:

显然上面的效果是很难满足我们实际的需求的,奈何也没有提供的属性可以更改,没有办法只好动手封装一个。

本篇的文章内容大致如下:

1、下拉和上拉效果展示

2、快速使用

3、具体实现

4、最后总结

一、下拉和上拉效果展示

效果呢很是简单,第一版只支持默认的效果,后续会逐渐支持自定义下拉请求头和上拉加载尾。

二、快速使用

私服和远程依赖,由于权限和审核问题,预计需要等到2024年第一季度面向所有开发者,所以,只能使用本地静态共享包和源码 两种使用方式,本地静态共享包类似Android中的aar依赖,直接复制到项目中即可。

本地静态共享包har包使用

首先,下载har包,点击下载

下载之后,把har包复制项目中,目录自己创建,如下,我创建了一个libs目录,复制进去。

引入之后,进行同步项目,点击Sync Now即可,当然了你也可以,将鼠标放置在报错处会出现提示,在提示框中点击Run 'ohpm install'

需要注意,@app/refresh,是用来区分目录的,可以自己定义,比如@aa/bb等,关于静态共享包的创建和使用,请查看如下我的介绍,这里就不过多介绍

HarmonyOS开发:走进静态共享包的依赖与使用

查看是否引用成功

无论使用哪种方式进行依赖,最终都会在使用的模块中,生成一个oh_modules文件,并创建源代码文件,有则成功,无则失败,如下:

代码使用

目前提供了三种用法,一种是ListView形式,就是单列表形式,一种是GridView形式,也就是网格列表形式,还有一种就是RefreshLayout形式,支持任何的组件形式,比如Column,Row等等。

1、ListView形式

TypeScript 复制代码
ListView({
       items: this.array, //数据源 数组
       itemLayout: (item, index) => this.itemLayout(item, index),//条目布局
       controller: this.controller, //控制器,负责关闭下拉和上拉
       onRefresh: () => {
         //下拉刷新
         this.controller.finishRefresh()
       },
       onLoadMore: () => {
         //上拉加载
         this.controller.finishLoadMore()
       }
     })
其他相关属性介绍

|-------------------|--------------|-----------------------|
| 属性 | 类型 | 概述 |
| listAttribute | ListAttr | ListView的相关属性 |
| listItemAttribute | ListItemAttr | ListView的Item相关属性 |
| marginHeader | number | 距离头部多少距离,用于顶部有固定组件时使用 |

ListAttr

|-----------------|---------------|-----------------------------------|
| 属性 | 类型 | 概述 |
| width | Length | 宽度 |
| height | Length | 高度 |
| backgroundColor | ResourceColor | 背景颜色,默认透明 |
| listDirection | Axis | 设置List组件排列方向。默认值:Axis.Vertical |
| divider | 对象 | 设置ListItem分割线样式,默认无分割线。 |
| scrollBar | BarState | 设置滚动条状态 |
| cachedCount | number | 设置列表中ListItem/ListItemGroup的预加载数量 |
| edgeEffect | EdgeEffect | 设置组件的滑动效果 |

ListItemAttr

|-----------------|---------------|-----------|
| 属性 | 类型 | 概述 |
| width | Length | 宽度 |
| height | Length | 高度 |
| backgroundColor | ResourceColor | 背景颜色,默认透明 |
| onClick | 回调方法 | 点击事件 |

2、GridView形式

TypeScript 复制代码
GridView({
        items: this.array,//数据源 数组
        itemLayout: (item, index) => this.itemLayout(item, index),//条目布局
        controller: this.controller,//控制器,负责关闭下拉和上拉
        onRefresh: () => {
          //下拉刷新
          this.controller.finishRefresh()//关闭下拉刷新
        },
        onLoadMore: () => {
          //上拉加载
          this.controller.finishLoadMore()//关闭上拉加载
        }
      })
其他相关属性介绍

|-------------------|--------------|-----------------------|
| 属性 | 类型 | 概述 |
| gridAttribute | GridAttr | GridView相关属性 |
| gridItemAttribute | GridItemAttr | GridView的Item相关属性 |
| marginHeader | number | 距离头部多少距离,用于顶部有固定组件时使用 |

GridAttr

|-----------------|-------------------------|-------------------------------------|
| 属性 | 类型 | 概述 |
| width | Length | 宽度 |
| height | Length | 高度 |
| backgroundColor | ResourceColor | 背景颜色,默认透明 |
| columnsTemplate | string | 设置当前网格布局列的数量,不设置时默认2列 |
| rowsTemplate | string | 设置当前网格布局行的数量,不设置时默认1行。 |
| columnsGap | Length | 设置列与列的间距。默认值:0 |
| rowsGap | Length | 设置行与行的间距。默认值:0 |
| scrollBar | BarState | 设置滚动条状态。默认值:BarState.Off |
| scrollBarColor | string / number / Color | 设置滚动条的颜色。 |
| scrollBarWidth | string / number / | 设置滚动条的宽度。 |
| cachedCount | number | 设置预加载的GridItem的数量,只在LazyForEach中生效。 |

GridItemAttr

|-----------------|------------------|-----------|
| 属性 | 类型 | 概述 |
| width | Length | 宽度 |
| height | Length | 高度 |
| margin | Margin / Length | 边距 |
| padding | Padding / Length | 内边距 |
| backgroundColor | ResourceColor | 背景颜色,默认透明 |
| onClick | 回调方法 | 点击事件 |

3、RefreshLayout形式

TypeScript 复制代码
RefreshLayout({
        controller: this.controller,//控制器,负责关闭下拉和上拉
        onRefresh: () => {
          //下拉刷新
          this.controller.finishRefresh() //关闭下拉刷新
        }, onLoadMore: () => {
          //上拉加载
          this.controller.finishLoadMore() //关闭上拉加载
        } }) {
        //可以是任何组件 List/Grid/Column/Row/Text/......
         
      }

4、头部固定组件方式

这种情况也颇为常见,就是列表在一个固定的组件下方,如下图所示,那么这种实现方式有一个潜在的约束,那就是,必须使用Stack作为根布局,并且头组件在刷新组件下方。

项目代码实现

TypeScript 复制代码
Stack() {
      ListView({
        items: this.array, //数据源 数组
        itemLayout: (item, index) => this.itemLayout(item, index),
        controller: this.controller, //控制器,负责关闭下拉和上拉
        marginHeader: 80,
        onRefresh: () => {
          //下拉刷新
          this.controller.finishRefresh()
        },
        onLoadMore: () => {
          //上拉加载
          this.controller.finishLoadMore()
        }
      })
 
 
      Row() {
        Text("我是标题")
      }.width("100%")
      .height(80)
      .backgroundColor(Color.Pink)
      .justifyContent(FlexAlign.Center)
 
    
    }.alignContent(Alignment.Top)

三、具体实现

实现起来无比的简单,所谓的头和尾,均在列表组件的上下位置,使用offset属性控制其位置,默认在屏幕外部,等手势移动的时候,慢慢展示出头,尾部的话一般也在屏幕外,考虑到列表的展示,会根据数据的多少进行控制,尾部尽量设置在列表的下方即可。

手势往下拉时,改变offset,缓缓地展示出来。

后续等其他功能完善之后,会进行源码地一个解析,请大家持续关注。

四、最后总结

Demo地址:

https://github.com/AbnerMing888/HarmonyOsRefresh

目前支持默认的下拉刷新头和上拉加载尾,暂时不支持自定义,后续有时间了就会暴露出来,大家在使用的时候,特别是RefreshLayout形式,一定要自己控制下拉和上拉的状态,也就是什么时候执行上拉,什么时候执行下拉,举例:如果是一个垂直的列表,那么索引为0可见,即可下拉刷新,索引为最后一个,即可上拉加载。