# SVRefresh **Repository Path**: mervin1024/SVRefresh ## Basic Information - **Project Name**: SVRefresh - **Description**: SVRefresh 是一款 OpenHarmony 环境下,基于 ArkUI 封装的下拉刷新、上拉加载组件。 - **Primary Language**: TypeScript - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 11 - **Forks**: 0 - **Created**: 2024-02-28 - **Last Updated**: 2025-04-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: HarmonyOS组件, UI ## README # SVRefresh ### 介绍 > SVRefresh 是一款 OpenHarmony 环境下,基于 ArkUI 封装的下拉刷新、上拉加载组件。 > > 支持主动触发刷新、开启/关闭刷新。上拉加载支持拖拽触发和完全展示自动触发。 > > 支持深度下拉事件,下拉进度超出更多距离时触发。一般用作页面跳转等。 > > 支持设置 header 部位的 backgroundView,可用作运营位等。 ### 效果展示 ![Refresh](https://gitee.com/mervin1024/SVRefresh/raw/master/gifs/refresh.gif)![Refresh](https://gitee.com/mervin1024/SVRefresh/raw/master/gifs/loadMore.gif) ### 安装教程 ```shell ohpm install @mervin/svrefresh ``` ### 使用说明 #### 使用示例 ``` import { FooterLoadMoreStatus, HeaderRefreshStatus, SVRefresh } from '@mervin/SVRefresh' @Entry @Component struct Index { // 用来控制刷新状态 @State private refreshStatus: HeaderRefreshStatus = HeaderRefreshStatus.inactive // 用来控制加载状态 @State private loadMoreStatus: FooterLoadMoreStatus = FooterLoadMoreStatus.inactive build() { Column() { SVRefresh({ /// 状态双向同步 refreshStatus: this.refreshStatus, loadMoreStatus: this.loadMoreStatus, /// 参数 Scroller 必须绑定滚动组件 childList: (scroller) => { this.listViewBuilder(scroller) }, /// 可选:传入已经初始化的 Scroller | ListScroller。不传则由 SVRefresh 内部自行初始化 Scroller /// scroller: this.scroller, /// 可选配置 refreshOptions: { /// 底部完全露出即加载更多,无需拖拽。不传默认为 true isAutoLoadMore: true, /// 深度刷新,下拉更多距离时触发。不传默认为 false deepRefreshEnable: false, }, /// 触发刷新的回调 onRefreshing: () => { this.viewModel.onRefreshing(() => { this.refreshStatus = HeaderRefreshStatus.inactive if (this.loadMoreStatus == FooterLoadMoreStatus.noMoreData) { this.loadMoreStatus = FooterLoadMoreStatus.inactive } }) }, /// 触发深度下拉刷新 onDeepRefreshing: () => { this.refreshStatus = HeaderRefreshStatus.inactive /// 长下拉触发页面跳转事件 router.pushUrl({ url: 'pages/DeepRefreshView' }, router.RouterMode.Standard, (err) => { if (err) { console.log(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`) } }) }, /// 触发加载的回调 onLoadingMore: () => { this.viewModel.onLoadMore((hasMoreData) => { this.loadMoreStatus = hasMoreData ? FooterLoadMoreStatus.inactive : FooterLoadMoreStatus.noMoreData }) }, /// 自定义 header headerUI: (state) => { this.testHeaderBuilder(state) }, /// header 背景 view headerBackgroundUI: () => { this.headerBackgroundView() } }) } } @Builder private listViewBuilder(scroller: Scroller) { List({ space: 20, scroller: scroller }) .height("100%") .edgeEffect(EdgeEffect.Spring, { alwaysEnabled: true }) /*不要设置为 Fade,拖动至边缘会一直显示 Fade 效果,很难看*/ } @Builder testHeaderBuilder($$: RefreshStateImp) { TestRefreshHeader({ state: $$.state }) } @Builder headerBackgroundView() { Text('backgroundView') .fontColor('#FF2E43') .fontSize(18) .linearGradient({ direction: GradientDirection.Top, colors: [['#551A1A1A', 0.0], ['#221A1A1A', 0.3], ['#001A1A1A', 1.0]] }) .textAlign(TextAlign.Center) .width('100%') .height(250) } } @Component struct TestRefreshHeader { @Link state: RefreshState ///... } ``` 其中List组件的 edgeEffect 属性不要设置为(EdgeEffect.Fade),展示效果不好 #### 属性(接口)说明 #### SVRefresh 组件属性 | 名称 | 参数类型 | 描述 | 必填 | |:-------------------:|:------------------------------------------------:|:------------------------------------------------------:|:--:| | childList | @BuilderParam```($$: Scroller) => void``` | 自定义主体布局,内部有列表或宫格组件,需绑定参数 scroller | ✅ | | refreshStatus | HeaderRefreshStatus | 头部刷新组件状态,双向绑定 | ✅ | | loadMoreStatus | FooterLoadMoreStatus | 尾部刷新组件状态,双向绑定 | ✅ | | onRefreshing | ```() => void ``` | 下拉刷新回调 | 否 | | onDeepRefreshing | ```() => void ``` | 深度下拉事件回调 | 否 | | onLoadingMore | ```() => void``` | 上拉加载回调 | 否 | | scroller | Scroller | 由外部初始化与列表绑定的 Scroller。可以不传,SVRefresh 内部会自行初始化 Scroller | 否 | | refreshOptions | SVRefreshOptions | 刷新组件相关配置:如 header、footer 的高度,是否开启弹性效果,是否自动触发底部加载 | 否 | | headerUI | @BuilderParam```($$: RefreshStateImp) => void``` | 自定义下拉刷新组件,不传为默认样式 | 否 | | footerUI | @BuilderParam```($$: RefreshStateImp) => void``` | 自定义上拉加载组件,不传为默认样式 | 否 | | headerBackgroundUI | @BuilderParam```() => void``` | 作为 headerUI 的 background 展示的 自定义UI,展示范围可以超出 header 的高度 | 否 | | componentOptions | SVRefreshComponentOptions | 默认刷新组件的 UI 配置,都是默认刷新控件的样式,使用自定义控件不需要赋值 | 否 | | onHeaderStateChange | ```(state: RefreshState) => void``` | header 刷新状态改变回调 | 否 | | onFooterStateChange | ```(state: RefreshState) => void``` | footer 刷新状态改变回调 | 否 | #### HeaderRefreshStatus枚举说明 可同步触发刷新组件的状态改变 | 名称 | 枚举值 | 描述 | |:--------------:|:---:|:----------------------------:| | hidden | 0 | 隐藏状态,禁用下拉刷新 | | inactive | 1 | 普通闲置状态,可触发刷新 | | refreshing | 2 | 正在刷新中的状态,主动赋值列表会滚动到顶部并触发刷新 | | deepRefreshing | 3 | 正在深度下拉刷新状态,主动赋值列表会滚动到顶部并触发事件 | #### FooterLoadMoreStatus枚举说明 可同步触发加载组件的状态改变 | 名称 | 枚举值 | 描述 | |:----------:|:---:|:-------------------------------:| | hidden | 0 | 隐藏状态,禁用上拉加载 | | inactive | 1 | 普通闲置状态,可触发加载 | | loading | 2 | 正在加载中的状态,主动赋值可以触发加载回调,但不会触发列表滚动 | | noMoreData | 3 | 无更多数据状态,展示但是不可触发刷新 | #### SVRefreshOptions对象说明 刷新组件相关配置,均为可选值 | 参数名 | 类型 | 描述 | 默认值 | |:--------------------------------:|:-------:|:---------------------------------------------------:|:-----:| | headerHeight | number | 下拉刷新控件的展示高度,同时也是触发下拉事件的高度 | 64 | | footerHeight | number | 上拉加载控件的展示高度,同时也是触发上拉事件的高度 | 54 | | isAutoLoadMore | boolean | 可以控制上拉加载组件的触发方式,自动 or 拖拽 | true | | onlyAutoLoadMoreOnceOnSingleDrag | boolean | 当`isAutoLoadMore`为`true`时,可以控制单次拖拽期间内只能触发一次 loading | false | | headerBounces | boolean | 下拉是否支持弹性效果 | true | | footerBounces | boolean | 上拉是否支持弹性效果 | true | | deepRefreshEnable | boolean | 是否支持深度下拉事件 | false | | deepRefreshTriggersHeight | number | 触发深度下拉事件的偏移量,不能低于 headerHeight | 125 | #### SVRefreshComponentOptions对象说明 都是默认刷新控件的样式,使用自定义控件不需要关心这个属性 | 参数名 | 类型 | 描述 | 默认值 | |:-------------------------:|:-------------------------------------:|:-----------------------:|:------------:| | headerFont | Font | 默认 header 的字体 | { size: 16 } | | footerFont | Font | 默认 footer 的字体 | { size: 16 } | | headerLoadingProgressSize | length | header 的默认 loading 组件尺寸 | 36 | | footerLoadingProgressSize | length | footer 的默认 loading 组件尺寸 | 36 | | headerText | ```(state: RefreshState) => string``` | 各刷新状态下 header 展示的文字 | - | | footerText | ```(state: RefreshState) => string``` | 各刷新状态下 footer 展示的文字 | - | #### RefreshState枚举说明 刷新组件 UI 展示的的不同阶段 | 名称 | 枚举值 | 描述 | |:--------------:|:---:|:-----------------------------------------------------:| | hidden | 0 | 隐藏禁用状态 | | inactive | 1 | 普通闲置状态,可触发加载 | | drag | 2 | 下拉中但未达到刷新距离 | | overDrag | 3 | 松开就可以进行刷新的状态,footer 的 isAutoLoadMore 为 true 时不会走到这个状态 | | refreshing | 4 | 正在刷新中的状态 | | noMoreData | 5 | 所有数据加载完毕,没有更多的数据了。仅 footer 可以有这个状态 | | deepPulling | 6 | 下滑至更高的 offset ,松开触发 deep 回调。仅 header 可以有这个状态 | | deepRefreshing | 7 | 下滑至更高的 offset 触发,不再走正常刷新逻辑。仅 header 可以有这个状态 | --- ### 约束与限制 在下述版本验证通过: - DevEco Studio: 4.1 Canary(4.1.3.500), SDK: API11 (4.1.0.36) ### TODO LIST 1. 使用 List 嵌套模式实现刷新,可以做到 footer 自动贴在尾部数据之后,而不是一定要拖拽才能出现 ### 贡献代码 使用过程中发现任何问题都可以提 [Issue](https://gitee.com/mervin1024/SVRefresh/issues) 给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/mervin1024/SVRefresh/pulls) 。 ### 开源协议 本项目基于 [Apache License 2.0](https://gitee.com/openharmony-sig/PullToRefresh/blob/master/LICENSE) ,请自由地享受和参与开源。