From 48044af6b78ddd6294c01a65d5de2baee104c5cd Mon Sep 17 00:00:00 2001 From: liangguirong Date: Fri, 12 Jul 2024 11:44:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E7=89=88=E8=A3=85=E9=A5=B0=E5=99=A8?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liangguirong --- README.md | 99 ++++++----- build-profile.json5 | 5 +- changelog.md | 8 + entry/oh-package.json5 | 2 +- entry/src/main/ets/pages/customConfig.ets | 50 +++--- .../src/main/ets/pages/customRefreshAnim.ets | 23 +-- entry/src/main/ets/pages/fullScreen.ets | 14 +- entry/src/main/ets/pages/interface.test.ets | 154 ++++++++++-------- entry/src/main/ets/pages/lazyForEachGuide.ets | 63 ++++--- entry/src/main/ets/pages/quickStart.ets | 11 +- entry/src/main/ets/pages/tabsTestPage.ets | 19 +-- .../ohosTest/ets/testability/pages/Index.ets | 4 +- library/oh-package.json5 | 2 +- .../PullToRefresh/PullToRefresh.ets | 47 +++--- oh-package.json5 | 2 +- 15 files changed, 273 insertions(+), 230 deletions(-) diff --git a/README.md b/README.md index f3cf6fa..83dcebc 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ import { PullToRefresh } from '@ohos/pulltorefresh' private scroller: Scroller = new Scroller(); PullToRefresh({ -// 必传项,列表组件所绑定的数据 -data: $data, +// 可选项,列表组件所绑定的数据 +data: this.data, // 必传项,需绑定传入主体布局内的列表或宫格组件 scroller: this.scroller, // 必传项,自定义主体布局,内部有列表或宫格组件 @@ -43,7 +43,7 @@ onRefresh: () => { // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据 setTimeout(() => { resolve('刷新成功'); - this.data = this.dataNumbers; + this.data = [...this.dataNumbers]; }, 2000); }); }, @@ -61,9 +61,22 @@ customLoad: null, customRefresh: null, }) ``` -其中List组件需要设置edgeEffect属性为(EdgeEffect.None) 设置属性示例和设置自定义动画示例请看[示例entry](https://gitee.com/openharmony-sig/PullToRefresh/tree/master/entry/src/main/ets/pages) + +### 使用限制 +1、目前只支持List、Scroll、Tabs、Grid和WaterFlow系统容器组件; + +2、不支持设置系统容器组件的弹簧效果和阴影效果,使用时需要将系统组件edgeEffect属性的值设置为(EdgeEffect.None); + +3、不支持页面触底时自动触发上拉加载功能; + +4、不支持在页面数据不满一屏时触发上拉加载功能; + +5、不支持通过代码的方式去触发下拉刷新功能; + +6、不支持在下拉刷新动画结束时提供手势结束的回调; + ### 支持lazyForEarch的数据作为数据源 LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当LazyForEach在滚动容器中使用了,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用 **接口描述:** @@ -102,53 +115,51 @@ interface DataChangeListener { ### PullToRefresh组件属性 -| 属性 | 类型 | 释义 | 默认值 | -| :------------------:| :-------------------------------------------------------------: | :---------------------------: | :----------------------------: | -| data | Object[] | 列表或宫格组件所绑定的数据 | undefined | -| scroller | Scroller | 列表或宫格组件所绑定的Scroller对象 | undefined | -| customList | ```() => void ``` | 自定义主体布局,内部有列表或宫格组件 | undefined | -| refreshConfigurator | PullToRefreshConfigurator | 组件属性配置 | PullToRefreshConfigurator | -| mWidth | Length | 容器宽 | undefined(自适应) | -| mHeight | Length | 容器高 | undefined(自适应) | -| onRefresh | ```() => Promise``` | 下拉刷新回调 | 1秒后结束下拉刷新动画并提示“刷新失败” | -| onLoadMore | ```() => Promise``` | 上拉加载更多回调 | 1秒后结束上拉加载动画 | -| customRefresh | ```() => void ``` | 自定义下拉刷新动画布局 | undefined | -| onAnimPullDown | ```(value?: number, width?: number, height?: number) => void``` | 下拉中回调 | undefined | -| onAnimRefreshing | ```(value?: number, width?: number, height?: number) => void``` | 刷新中回调 | undefined | -| customLoad | ```() => void``` | 自定义上拉加载动画布局 | undefined | -| onAnimPullUp | ```(value?: number, width?: number, height?: number) => void``` | 上拉中回调 | undefined | -| onAnimLoading | ```(value?: number, width?: number, height?: number) => void``` | 加载中回调 | undefined | +| 属性 | 类型 | 释义 | 默认值 | +| :------------------:|:----------------------------------------------------------------------------------:|:---------------------:| :----------------------------: | +| data | Object[] \| undefined | 列表或宫格组件所绑定的数据 | undefined | +| scroller | Scroller | 列表或宫格组件所绑定的Scroller对象 | undefined | +| customList | ```() => void ``` | 自定义主体布局,内部有列表或宫格组件 | undefined | +| refreshConfigurator | PullToRefreshConfigurator | 组件属性配置 | PullToRefreshConfigurator | +| mWidth | Length | 容器宽 | undefined(自适应) | +| mHeight | Length | 容器高 | undefined(自适应) | +| onRefresh | ```() => Promise``` | 下拉刷新回调 | 1秒后结束下拉刷新动画并提示“刷新失败” | +| onLoadMore | ```() => Promise``` | 上拉加载更多回调 | 1秒后结束上拉加载动画 | +| customRefresh | ```() => void ``` | 自定义下拉刷新动画布局 | undefined | +| onAnimPullDown | ```(value?: number, width?: number, height?: number) => void \| undefined ``` | 下拉中回调 | undefined | +| onAnimRefreshing | ```(value?: number, width?: number, height?: number) => void \| undefined ``` | 刷新中回调 | undefined | +| customLoad | ```() => void``` | 自定义上拉加载动画布局 | undefined | +| onAnimPullUp | ```(value?: number, width?: number, height?: number) => void \| undefined ``` | 上拉中回调 | undefined | +| onAnimLoading | ```(value?: number, width?: number, height?: number) => void \| undefined ``` | 加载中回调 | undefined | ### PullToRefreshConfigurator类接口 -| 接口 | 参数类型 | 释义 | 默认值 | -| :------------------------:| :-------------------------: | :-----------------------: | :--------------: | -| setHasRefresh | boolean | 是否具有下拉刷新功能 | true | -| setHasLoadMore | boolean | 是否具有上拉加载功能 | true | -| setMaxTranslate | number | 可下拉上拉的最大距离 | 100 | -| setSensitivity | number | 下拉上拉灵敏度 | 0.7 | -| setListIsPlacement | boolean | 滑动结束后列表是否归位 | true | -| setAnimDuration | number | 滑动结束后,回弹动画执行时间 | 150 | -| setRefreshHeight | number | 下拉动画高度 | 30 | -| setRefreshColor | string | 下拉动画颜色 | '#999999' | -| setRefreshBackgroundColor | ResourceColor | 下拉动画区域背景色 | 'rgba(0,0,0,0)' | -| setRefreshTextColor | ResourceColor | 下拉加载完毕后提示文本的字体颜色 | '#999999' | -| setRefreshTextSize | number 或 string 或 Resource | 下拉加载完毕后提示文本的字体大小 | 18 | -| setRefreshAnimDuration | number | 下拉动画执行一次的时间 | 1000 | -| setLoadImgHeight | number | 上拉动画中图片的高度 | 30 | -| setLoadBackgroundColor | ResourceColor | 上拉动画区域背景色 | 'rgba(0,0,0,0)' | -| setLoadTextColor | ResourceColor | 上拉文本的字体颜色 | '#999999' | -| setLoadTextSize | number 或 string 或 Resource | 上拉文本的字体大小 | 18 | -| setLoadTextPullUp1 | string | 上拉1阶段文本 | '正在上拉刷新...' | -| setLoadTextPullUp2 | string | 上拉2阶段文本 | '放开刷新' | -| setLoadTextLoading | string | 上拉加载更多中时的文本 | '正在玩命加载中...' | +| 接口 | 参数类型 | 释义 | 默认值 | +| :------------------------:| :-------------------------: |:--------------------------:| :--------------: | +| setHasRefresh | boolean | 是否具有下拉刷新功能 | true | +| setHasLoadMore | boolean | 是否具有上拉加载功能 | true | +| setMaxTranslate | number | 可下拉上拉的最大距离 | 100 | +| setSensitivity | number | 下拉上拉灵敏度 | 0.7 | +| setListIsPlacement | boolean | 滑动结束后列表是否归位 | true | +| setAnimDuration | number | 滑动结束后,回弹动画执行时间 | 150 | +| setRefreshHeight | number | 下拉动画高度 | 30 | +| setRefreshColor | string | 下拉动画颜色 | '#999999' | +| setRefreshBackgroundColor | ResourceColor | 下拉动画区域背景色 | 'rgba(0,0,0,0)' | +| setRefreshTextColor | ResourceColor | 下拉加载完毕后提示文本的字体颜色 | '#999999' | +| setRefreshTextSize | number 或 string 或 Resource | 下拉加载完毕后提示文本的字体大小 | 18 | +| setRefreshAnimDuration | number | 下拉动画执行一次的时间,仅在自定义下拉刷新动画时有效 | 1000 | +| setLoadImgHeight | number | 上拉动画中图片的高度 | 30 | +| setLoadBackgroundColor | ResourceColor | 上拉动画区域背景色 | 'rgba(0,0,0,0)' | +| setLoadTextColor | ResourceColor | 上拉文本的字体颜色 | '#999999' | +| setLoadTextSize | number 或 string 或 Resource | 上拉文本的字体大小 | 18 | +| setLoadTextPullUp1 | string | 上拉1阶段文本 | '正在上拉刷新...' | +| setLoadTextPullUp2 | string | 上拉2阶段文本 | '放开刷新' | +| setLoadTextLoading | string | 上拉加载更多中时的文本 | '正在玩命加载中...' | ## 约束与限制 在下述版本验证通过: -- DevEco Studio: 4.1 Canary(4.1.3.317), SDK: API11 (4.1.0.36) -- DevEco Studio: 4.0 (4.0.3.512), SDK: API10 (4.0.10.9) -- DevEco Studio: 4.0 Canary2(4.0.3.300), SDK: API10 (4.0.8.6) +- DevEco Studio: NEXT Developer Beta2(5.0.3.427), SDK: API11 (5.0.0.31) ## 贡献代码 diff --git a/build-profile.json5 b/build-profile.json5 index 99857ab..be6d64e 100644 --- a/build-profile.json5 +++ b/build-profile.json5 @@ -4,9 +4,8 @@ { "name": "default", "signingConfig": "default", - "compileSdkVersion": 10, - "compatibleSdkVersion": 10, - "targetSdkVersion": 10, + "compileSdkVersion": 11, + "compatibleSdkVersion": 11, "runtimeOS": "OpenHarmony" } ], diff --git a/changelog.md b/changelog.md index dd38f1f..c91b01d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,11 @@ +## 2.1.0 + +1、新版装饰器语法整改 + +## 2.0.6 + +1、发布2.0.6正式版本 + ## 2.0.6-rc.0 1、修复自定义下拉刷新和自定义上拉加载在刷新完成之后页面残留的问题 diff --git a/entry/oh-package.json5 b/entry/oh-package.json5 index 30a222a..736cf27 100644 --- a/entry/oh-package.json5 +++ b/entry/oh-package.json5 @@ -4,7 +4,7 @@ "name": "entry", "description": "example description", "repository": {}, - "version": "2.0.6-rc.0", + "version": "2.1.0", "dependencies": { "@ohos/pulltorefresh": "file:../library" } diff --git a/entry/src/main/ets/pages/customConfig.ets b/entry/src/main/ets/pages/customConfig.ets index 5fee151..efe966b 100644 --- a/entry/src/main/ets/pages/customConfig.ets +++ b/entry/src/main/ets/pages/customConfig.ets @@ -15,44 +15,44 @@ import { PullToRefresh, PullToRefreshConfigurator } from '@ohos/pulltorefresh' @Entry -@Component +@ComponentV2 struct Index { - @State refreshText: string = ''; private dataNumbers: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; - private dataStrings: string[] = ['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录']; - @State data: string[] = this.dataStrings; + private dataStrings: string[] = + ['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录']; + @Local data: string[] = this.dataStrings; private scroller: Scroller = new Scroller(); private refreshConfigurator: PullToRefreshConfigurator = new PullToRefreshConfigurator(); aboutToAppear() { // 设置属性 this.refreshConfigurator - .setHasRefresh(true) // 是否具有下拉刷新功能 - .setHasLoadMore(true) // 是否具有上拉加载功能 - .setMaxTranslate(150) // 可下拉上拉的最大距离 - .setSensitivity(1) // 下拉上拉灵敏度 - .setListIsPlacement(false) // 滑动结束后列表是否归位 - .setAnimDuration(300) // 滑动结束后,回弹动画执行时间 - .setRefreshHeight(80) // 下拉动画高度 - .setRefreshColor('#ff0000') // 下拉动画颜色 - .setRefreshBackgroundColor('#ffbbfaf5') // 下拉动画区域背景色 - .setRefreshTextColor('red') // 下拉加载完毕后提示文本的字体颜色 - .setRefreshTextSize(25) // 下拉加载完毕后提示文本的字体大小 - .setRefreshAnimDuration(1000) // 下拉动画执行一次的时间 - .setLoadImgHeight(50) // 上拉图片高度 - .setLoadBackgroundColor('#ffbbfaf5') // 上拉动画区域背景色 - .setLoadTextColor('blue') // 上拉文本的字体颜色 - .setLoadTextSize(25) // 上拉文本的字体大小 - .setLoadTextPullUp1('请继续上拉...') // 上拉1阶段文本 - .setLoadTextPullUp2('释放即可刷新') // 上拉2阶段文本 + .setHasRefresh(true)// 是否具有下拉刷新功能 + .setHasLoadMore(true)// 是否具有上拉加载功能 + .setMaxTranslate(150)// 可下拉上拉的最大距离 + .setSensitivity(1)// 下拉上拉灵敏度 + .setListIsPlacement(false)// 滑动结束后列表是否归位 + .setAnimDuration(300)// 滑动结束后,回弹动画执行时间 + .setRefreshHeight(80)// 下拉动画高度 + .setRefreshColor('#ff0000')// 下拉动画颜色 + .setRefreshBackgroundColor('#ffbbfaf5')// 下拉动画区域背景色 + .setRefreshTextColor('red')// 下拉加载完毕后提示文本的字体颜色 + .setRefreshTextSize(25)// 下拉加载完毕后提示文本的字体大小 + .setRefreshAnimDuration(1000)// 下拉动画执行一次的时间 + .setLoadImgHeight(50)// 上拉图片高度 + .setLoadBackgroundColor('#ffbbfaf5')// 上拉动画区域背景色 + .setLoadTextColor('blue')// 上拉文本的字体颜色 + .setLoadTextSize(25)// 上拉文本的字体大小 + .setLoadTextPullUp1('请继续上拉...')// 上拉1阶段文本 + .setLoadTextPullUp2('释放即可刷新')// 上拉2阶段文本 .setLoadTextLoading('加载中...') // 上拉加载更多中时的文本 } build() { Column() { PullToRefresh({ - // 必传项,列表组件所绑定的数据 - data: $data, + // 可选项,列表组件所绑定的数据 + data: this.data, // 必传项,需绑定传入主体布局内的列表或宫格组件 scroller: this.scroller, // 必传项,自定义主体布局,内部有列表或宫格组件 @@ -72,7 +72,7 @@ struct Index { // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据 setTimeout(() => { resolve('刷新成功'); - this.data = this.dataNumbers; + this.data = [...this.dataNumbers]; }, 2000); }); }, diff --git a/entry/src/main/ets/pages/customRefreshAnim.ets b/entry/src/main/ets/pages/customRefreshAnim.ets index 542250a..f1ebaa9 100644 --- a/entry/src/main/ets/pages/customRefreshAnim.ets +++ b/entry/src/main/ets/pages/customRefreshAnim.ets @@ -13,16 +13,17 @@ * limitations under the License. */ import { PullToRefresh, PullToRefreshConfigurator } from '@ohos/pulltorefresh' + const pointSpace = 30; const pointJitterAmplitude = 10; @Entry -@Component +@ComponentV2 struct Index { - @State refreshText: string = ''; private dataNumbers: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; - private dataStrings: string[] = ['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录']; - @State data: string[] = this.dataStrings; + private dataStrings: string[] = + ['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录']; + @Local data: string[] = this.dataStrings; private scroller: Scroller = new Scroller(); private refreshConfigurator: PullToRefreshConfigurator = new PullToRefreshConfigurator(); private canvasSetting: RenderingContextSettings = new RenderingContextSettings(true); @@ -39,8 +40,8 @@ struct Index { build() { Column() { PullToRefresh({ - // 必传项,列表组件所绑定的数据 - data: $data, + // 可选项,列表组件所绑定的数据 + data: this.data, // 必传项,需绑定传入主体布局内的列表或宫格组件 scroller: this.scroller, // 必传项,自定义主体布局,内部有列表或宫格组件 @@ -55,8 +56,8 @@ struct Index { return new Promise((resolve, reject) => { // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据 setTimeout(() => { - resolve('刷新成功'); - this.data = this.dataNumbers; + resolve(''); + this.data = [...this.dataNumbers]; }, 2000); }); }, @@ -76,7 +77,7 @@ struct Index { }, // 可选项,下拉中回调 onAnimPullDown: (value, width, height) => { - if(value !== undefined && width !== undefined && height !== undefined) { + if (value !== undefined && width !== undefined && height !== undefined) { this.canvasRefresh.clearRect(0, 0, width, height); if (value <= 0.33) { this.drawPoint(width / 2, height / 2); @@ -92,7 +93,7 @@ struct Index { }, // 可选项,刷新中回调 onAnimRefreshing: (value, width, height) => { - if(value !== undefined && width !== undefined && height !== undefined){ + if (value !== undefined && width !== undefined && height !== undefined) { this.canvasRefresh.clearRect(0, 0, width, height); // 将value值由0到1循环变化变为-1到1反复变化 value = Math.abs(value * 2 - 1) * 2 - 1; @@ -121,7 +122,7 @@ struct Index { } } - private drawPoint(x: number, y: number): void{ + private drawPoint(x: number, y: number): void { this.canvasRefresh.beginPath(); this.canvasRefresh.arc(x, y, 3, 0, Math.PI * 2); this.canvasRefresh.fill(); diff --git a/entry/src/main/ets/pages/fullScreen.ets b/entry/src/main/ets/pages/fullScreen.ets index 2349670..18e4a88 100644 --- a/entry/src/main/ets/pages/fullScreen.ets +++ b/entry/src/main/ets/pages/fullScreen.ets @@ -15,20 +15,20 @@ import { PullToRefresh } from '@ohos/pulltorefresh' @Entry -@Component +@ComponentV2 struct Index { - @State refreshText: string = ''; private dataNumbers: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; - private dataStrings: string[] = ['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录']; - @State data: string[] = this.dataStrings; + private dataStrings: string[] = + ['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录']; + @Local data: string[] = this.dataStrings; // 需绑定列表或宫格组件 private scroller: Scroller = new Scroller(); build() { Column() { PullToRefresh({ - // 必传项,列表组件所绑定的数据 - data: $data, + // 可选项,列表组件所绑定的数据 + data: this.data, // 必传项,需绑定传入主体布局内的列表或宫格组件 scroller: this.scroller, // 必传项,自定义主体布局,内部有列表或宫格组件 @@ -42,7 +42,7 @@ struct Index { // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据 setTimeout(() => { resolve('刷新成功'); - this.data = this.dataNumbers; + this.data = [...this.dataNumbers]; }, 2000); }); }, diff --git a/entry/src/main/ets/pages/interface.test.ets b/entry/src/main/ets/pages/interface.test.ets index 09d710f..181b854 100644 --- a/entry/src/main/ets/pages/interface.test.ets +++ b/entry/src/main/ets/pages/interface.test.ets @@ -15,15 +15,19 @@ import router from '@ohos.router'; import promptAction from '@ohos.promptAction'; import mediaquery from '@ohos.mediaquery'; -import { PullToRefresh} from '@ohos/pulltorefresh/index' -class BasicDataSource implements IDataSource{ +import { PullToRefresh } from '@ohos/pulltorefresh/index' + +class BasicDataSource implements IDataSource { private listeners: DataChangeListener[] = new Array(); + public totalCount(): number { return 0; } + public getData(index: number): Object { return index; } + // 为LazyForEach组件向其数据源处添加listener监听 registerDataChangeListener(listener: DataChangeListener): void { if (this.listeners.indexOf(listener) < 0) { @@ -31,6 +35,7 @@ class BasicDataSource implements IDataSource{ this.listeners.push(listener); } } + // 为对应的LazyForEach组件在数据源处去除listener监听 unregisterDataChangeListener(listener: DataChangeListener): void { const pos = this.listeners.indexOf(listener); @@ -39,24 +44,28 @@ class BasicDataSource implements IDataSource{ this.listeners.splice(pos, 1); } } + // 通知LazyForEach组件需要重载所有子组件 notifyDataReload(): void { this.listeners.forEach(listener => { listener.onDataReloaded(); }) } + // 通知LazyForEach组件需要在index对应索引处添加子组件 notifyDataAdd(index: number): void { this.listeners.forEach(listener => { listener.onDataAdd(index); }) } + // 通知LazyForEach组件需要在index对应索引处添加子组件 notifyDataChange(index: number): void { this.listeners.forEach(listener => { listener.onDataChange(index); }) } + // 通知LazyForEach组件需要在index对应索引处删除该子组件 notifyDataDelete(index: number): void { this.listeners.forEach(listener => { @@ -73,47 +82,52 @@ class BasicDataSource implements IDataSource{ class MyDataSource extends BasicDataSource { private dataArray: string[] = []; + public totalCount(): number { return this.dataArray.length; } + public getData(index: number): Object { return this.dataArray[index]; } + public addData(index: number, data: string): void { this.dataArray.splice(index, 0, data); this.notifyDataAdd(index); } + public pushData(data: string): void { this.dataArray.push(data); this.notifyDataAdd(this.dataArray.length - 1); } - public clear():void{ + + public clear(): void { this.dataArray = []; } } + @Entry -@Component +@ComponentV2 struct MyComponent { - @State refreshText: string = ''; - @State data: MyDataSource = new MyDataSource(); + @Local data: MyDataSource = new MyDataSource(); // 需绑定列表或宫格组件 private scroller: Scroller = new Scroller(); - private timer:null|number=null; + private timer: null | number = null; + aboutToAppear() { for (let i = 1; i <= 20; i++) { this.data.pushData(`Hello ${i}`); } } + build() { - Column(){ - Column(){ + Column() { + Column() { PullToRefresh({ - // 必传项,列表组件所绑定的数据 - data: $data, // 必传项,需绑定传入主体布局内的列表或宫格组件 scroller: this.scroller, // 必传项,自定义主体布局,内部有列表或宫格组件 - customList:() => { + customList: () => { // 一个用@Builder修饰过的UI方法 this.getListView(); }, @@ -124,7 +138,7 @@ struct MyComponent { this.timer = setTimeout(() => { resolve('刷新成功'); console.log(' 刷新成功'); - this.data.addData(0,'ADD HEAD 0'); + this.data.addData(0, 'ADD HEAD 0'); }, 2000); }); }, @@ -132,7 +146,7 @@ struct MyComponent { onLoadMore: () => { return new Promise((resolve, reject) => { // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据 - this.timer=setTimeout(() => { + this.timer = setTimeout(() => { resolve(''); console.log('上拉加载完成'); this.data.pushData(`Hello ${this.data.totalCount()}`); @@ -142,96 +156,99 @@ struct MyComponent { customLoad: null, customRefresh: null, }) - } - Column(){ + + Column() { //添加this.data.totalCount接口的性能测试按钮 - Button('this.data.totalCount') - .width('90%') - .margin({top:20}) - .onClick(()=>{ - try { - const BASE_COUNT = 2000 // 循环次数:测试普通接口性能 - let startTime = new Date().getTime() - for(let index = 0;index { + try { + const BASE_COUNT = 2000 // 循环次数:测试普通接口性能 + let startTime = new Date().getTime() + for (let index = 0; index < BASE_COUNT; index++) { + this.data.totalCount() + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / 2000; + console.info(`${startTime},${endTime}`) + //循环2000次之后的平均时间 + promptAction.showToast({ message: "averageTime: " + averageTime + "us", duration: 2000 }); + } catch (e) { + promptAction.showToast({ message: JSON.stringify(e) }); + } - }) - } - Column(){ + }) + } + + Column() { //添加this.data.getData接口的性能测试按钮 Button('this.data.getData') .width('90%') - .margin({top:20}) - .onClick(()=>{ + .margin({ top: 20 }) + .onClick(() => { try { const BASE_COUNT = 2000 // 循环次数:测试普通接口性能 let startTime = new Date().getTime() - for(let index = 0;index{ + .margin({ top: 20 }) + .onClick(() => { try { const BASE_COUNT = 2000 // 循环次数:测试普通接口性能 let startTime = new Date().getTime() - for(let index = 0;index{ + .margin({ top: 20 }) + .onClick(() => { try { const BASE_COUNT = 2000 // 循环次数:测试普通接口性能 let startTime = new Date().getTime() - for(let index = 0;index { + List({ space: 3, scroller: this.scroller }) { + LazyForEach(this.data, (item: string, index?: number) => { ListItem() { Row() { - Text(item).fontSize(50) - //组件挂载显示触发 + Text(item).fontSize(50)//组件挂载显示触发 .onAppear(() => { - if(index){ - console.log(" onAppear: index="+index + ' content= ' +this.data.getData(index) ); + if (index) { + console.log(" onAppear: index=" + index + ' content= ' + this.data.getData(index)); } - }) - //组件卸载载显示触发 - .onDisAppear(()=>{ - if(index) { + })//组件卸载载显示触发 + .onDisAppear(() => { + if (index) { console.log(" onDisAppear: index=" + index + ' content= ' + this.data.getData(index)); } }) @@ -267,10 +282,9 @@ struct MyComponent { .divider({ strokeWidth: 1, color: 0x222222 }) .edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果 } + aboutToDisappear() { clearTimeout(this.timer); this.data.clear(); } - - } \ No newline at end of file diff --git a/entry/src/main/ets/pages/lazyForEachGuide.ets b/entry/src/main/ets/pages/lazyForEachGuide.ets index e0d8225..515b032 100644 --- a/entry/src/main/ets/pages/lazyForEachGuide.ets +++ b/entry/src/main/ets/pages/lazyForEachGuide.ets @@ -12,15 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { PullToRefresh} from '@ohos/pulltorefresh' -class BasicDataSource implements IDataSource{ +import { PullToRefresh } from '@ohos/pulltorefresh' + +class BasicDataSource implements IDataSource { private listeners: DataChangeListener[] = new Array(); + public totalCount(): number { return 0; } + public getData(index: number): Object { return index; } + // 为LazyForEach组件向其数据源处添加listener监听 registerDataChangeListener(listener: DataChangeListener): void { if (this.listeners.indexOf(listener) < 0) { @@ -28,6 +32,7 @@ class BasicDataSource implements IDataSource{ this.listeners.push(listener); } } + // 为对应的LazyForEach组件在数据源处去除listener监听 unregisterDataChangeListener(listener: DataChangeListener): void { const pos = this.listeners.indexOf(listener); @@ -36,24 +41,28 @@ class BasicDataSource implements IDataSource{ this.listeners.splice(pos, 1); } } + // 通知LazyForEach组件需要重载所有子组件 notifyDataReload(): void { this.listeners.forEach(listener => { listener.onDataReloaded(); }) } + // 通知LazyForEach组件需要在index对应索引处添加子组件 notifyDataAdd(index: number): void { this.listeners.forEach(listener => { listener.onDataAdd(index); }) } + // 通知LazyForEach组件需要在index对应索引处添加子组件 notifyDataChange(index: number): void { this.listeners.forEach(listener => { listener.onDataChange(index); }) } + // 通知LazyForEach组件需要在index对应索引处删除该子组件 notifyDataDelete(index: number): void { this.listeners.forEach(listener => { @@ -70,46 +79,51 @@ class BasicDataSource implements IDataSource{ class MyDataSource extends BasicDataSource { private dataArray: string[] = []; + public totalCount(): number { return this.dataArray.length; } + public getData(index: number): Object { return this.dataArray[index]; } + public addData(index: number, data: string): void { this.dataArray.splice(index, 0, data); this.notifyDataAdd(index); } + public pushData(data: string): void { this.dataArray.push(data); this.notifyDataAdd(this.dataArray.length - 1); } - public clear():void{ + + public clear(): void { this.dataArray = []; } } + @Entry -@Component +@ComponentV2 struct MyComponent { - @State refreshText: string = ''; - @State data: MyDataSource = new MyDataSource(); + @Local data: MyDataSource = new MyDataSource(); // 需绑定列表或宫格组件 private scroller: Scroller = new Scroller(); - private timer:null|number=null; + private timer: null | number = null; + aboutToAppear() { for (let i = 1; i <= 20; i++) { this.data.pushData(`Hello ${i}`); } } + build() { Column() { PullToRefresh({ - // 必传项,列表组件所绑定的数据 - data: $data, // 必传项,需绑定传入主体布局内的列表或宫格组件 scroller: this.scroller, // 必传项,自定义主体布局,内部有列表或宫格组件 - customList:() => { + customList: () => { // 一个用@Builder修饰过的UI方法 this.getListView(); }, @@ -120,7 +134,7 @@ struct MyComponent { this.timer = setTimeout(() => { resolve('刷新成功'); console.log(' 刷新成功'); - this.data.addData(0,'ADD HEAD 0'); + this.data.addData(0, 'ADD HEAD 0'); }, 2000); }); }, @@ -128,10 +142,12 @@ struct MyComponent { onLoadMore: () => { return new Promise((resolve, reject) => { // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据 - this.timer=setTimeout(() => { + this.timer = setTimeout(() => { resolve(''); console.log('上拉加载完成'); - this.data.pushData(`Hello ${this.data.totalCount()}`); + for (let index = 0; index < 30; index++) { + this.data.pushData(`Hello ${this.data.totalCount()}`); + } }, 2000); }); }, @@ -143,20 +159,18 @@ struct MyComponent { @Builder private getListView() { - List({ space: 3 , scroller: this.scroller }) { - LazyForEach(this.data, (item: string, index?:number) => { + List({ space: 3, scroller: this.scroller }) { + LazyForEach(this.data, (item: string, index?: number) => { ListItem() { Row() { - Text(item).fontSize(50) - //组件挂载显示触发 + Text(item).fontSize(50)//组件挂载显示触发 .onAppear(() => { - if(index){ - console.log(" onAppear: index="+index + ' content= ' +this.data.getData(index) ); + if (index) { + console.log(" onAppear: index=" + index + ' content= ' + this.data.getData(index)); } - }) - //组件卸载载显示触发 - .onDisAppear(()=>{ - if(index) { + })//组件卸载载显示触发 + .onDisAppear(() => { + if (index) { console.log(" onDisAppear: index=" + index + ' content= ' + this.data.getData(index)); } }) @@ -168,10 +182,9 @@ struct MyComponent { .divider({ strokeWidth: 1, color: 0x222222 }) .edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果 } + aboutToDisappear() { clearTimeout(this.timer); this.data.clear(); } - - } \ No newline at end of file diff --git a/entry/src/main/ets/pages/quickStart.ets b/entry/src/main/ets/pages/quickStart.ets index 005662c..e2cd124 100644 --- a/entry/src/main/ets/pages/quickStart.ets +++ b/entry/src/main/ets/pages/quickStart.ets @@ -15,20 +15,19 @@ import { PullToRefresh } from '@ohos/pulltorefresh' @Entry -@Component +@ComponentV2 struct Index { - @State refreshText: string = ''; private dataNumbers: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; private dataStrings: string[] = ['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录']; - @State data: string[] = this.dataStrings; + @Local data: string[] = this.dataStrings; // 需绑定列表或宫格组件 private scroller: Scroller = new Scroller(); build() { Column() { PullToRefresh({ - // 必传项,列表组件所绑定的数据 - data: $data, + // 可选项,列表组件所绑定的数据 + data: this.data, // 必传项,需绑定传入主体布局内的列表或宫格组件 scroller: this.scroller, // 必传项,自定义主体布局,内部有列表或宫格组件 @@ -42,7 +41,7 @@ struct Index { // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据 setTimeout(() => { resolve('刷新成功'); - this.data = this.dataNumbers; + this.data = [...this.dataNumbers]; }, 2000); }); }, diff --git a/entry/src/main/ets/pages/tabsTestPage.ets b/entry/src/main/ets/pages/tabsTestPage.ets index bad11dd..d38e974 100644 --- a/entry/src/main/ets/pages/tabsTestPage.ets +++ b/entry/src/main/ets/pages/tabsTestPage.ets @@ -15,11 +15,11 @@ import { PullToRefresh } from '@ohos/pulltorefresh' @Entry -@Component +@ComponentV2 struct TabsExample { - @State fontColor: string = '#182431' - @State selectedFontColor: string = '#007DFF' - @State currentIndex: number = 0 + @Local fontColor: string = '#182431' + @Local selectedFontColor: string = '#007DFF' + @Local currentIndex: number = 0 private controller: TabsController = new TabsController() @Builder TabBuilder(index: number, name: string) { @@ -72,20 +72,19 @@ struct TabsExample { } } -@Component +@ComponentV2 struct PullToRefreshDemo { - @State refreshText: string = ''; private dataNumbers: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; private dataStrings: string[] = ['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录']; - @State data: string[] = this.dataStrings; + @Local data: string[] = this.dataStrings; // 需绑定列表或宫格组件 private scroller: Scroller = new Scroller(); build() { Column() { PullToRefresh({ - // 必传项,列表组件所绑定的数据 - data: $data, + // 可选项,列表组件所绑定的数据 + data: this.data, // 必传项,需绑定传入主体布局内的列表或宫格组件 scroller: this.scroller, // 必传项,自定义主体布局,内部有列表或宫格组件 @@ -99,7 +98,7 @@ struct PullToRefreshDemo { // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据 setTimeout(() => { resolve('刷新成功'); - this.data = this.dataNumbers; + this.data = [...this.dataNumbers]; }, 2000); }); }, diff --git a/entry/src/ohosTest/ets/testability/pages/Index.ets b/entry/src/ohosTest/ets/testability/pages/Index.ets index 4ca1473..111d771 100644 --- a/entry/src/ohosTest/ets/testability/pages/Index.ets +++ b/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -15,12 +15,12 @@ import hilog from '@ohos.hilog'; @Entry -@Component +@ComponentV2 struct Index { aboutToAppear() { hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); } - @State message: string = 'Hello World' + @Local message: string = 'Hello World' build() { Row() { Column() { diff --git a/library/oh-package.json5 b/library/oh-package.json5 index ac5fe2a..9bea51c 100644 --- a/library/oh-package.json5 +++ b/library/oh-package.json5 @@ -14,7 +14,7 @@ "main": "index.ets", "repository": "https://gitee.com/openharmony-sig/PullToRefresh", "type": "module", - "version": "2.0.6-rc.0", + "version": "2.1.0", "dependencies": {}, "tags": [ "UI" diff --git a/library/src/main/ets/components/PullToRefresh/PullToRefresh.ets b/library/src/main/ets/components/PullToRefresh/PullToRefresh.ets index 0c7ba71..bc34bae 100644 --- a/library/src/main/ets/components/PullToRefresh/PullToRefresh.ets +++ b/library/src/main/ets/components/PullToRefresh/PullToRefresh.ets @@ -23,22 +23,22 @@ const IS_PULL_UP_1 = 41; const IS_PULL_UP_2 = 42; const IS_LOADING = 5; -@Component +@ComponentV2 export struct PullToRefresh { - @Link data: Object[]; - scroller: Scroller = new Scroller(); + @Param data?: Object[] | undefined = undefined; + @Param scroller: Scroller = new Scroller(); @BuilderParam customList?: () => void; - refreshConfigurator?: PullToRefreshConfigurator; - mWidth?: Length = '100%'; - mHeight?: Length = '100%'; - onRefresh?: () => Promise = () => { + @Param refreshConfigurator?: PullToRefreshConfigurator = new PullToRefreshConfigurator(); + @Param mWidth?: Length = '100%'; + @Param mHeight?: Length = '100%'; + @Param onRefresh?: () => Promise = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve('刷新失败'); }, 1000); }); }; - onLoadMore?: () => Promise = () => { + @Param onLoadMore?: () => Promise = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(''); @@ -48,21 +48,21 @@ export struct PullToRefresh { // 自定义下拉动画 @BuilderParam customRefresh?: (() => void) | null; //开启自定义下拉动画 - onAnimPullDown?: (value?: number, width?: number, height?: number) => void; - onAnimRefreshing?: (value?: number, width?: number, height?: number) => void; + @Param onAnimPullDown?: (value?: number, width?: number, height?: number) => void | undefined = undefined; + @Param onAnimRefreshing?: (value?: number, width?: number, height?: number) => void | undefined = undefined; // 自定义上拉动画 @BuilderParam customLoad?: (() => void) | null; - onAnimPullUp?: (value?: number, width?: number, height?: number) => void; - onAnimLoading?: (value?: number, width?: number, height?: number) => void; + @Param onAnimPullUp?: (value?: number, width?: number, height?: number) => void | undefined = undefined; + @Param onAnimLoading?: (value?: number, width?: number, height?: number) => void | undefined = undefined; //-----------------------------以下为组件内自用属性-----------------------------// - @State private mHeightNumber?: number = 0; - @State private trYTop?: number = 0; - @State private trYBottom?: number = 0; - @State private state?: number = IS_FREE; - @State private refreshText?: string = ''; - @State private loadText?: string = ''; - @State private angle1?: number | string = 0; - @State private angle2?: number | string = 0; + @Local private mHeightNumber?: number = 0; + @Local private trYTop?: number = 0; + @Local private trYBottom?: number = 0; + @Local private state?: number = IS_FREE; + @Local private refreshText?: string = ''; + @Local private loadText?: string = ''; + @Local private angle1?: number | string = 0; + @Local private angle2?: number | string = 0; private mWidthNumber?: number = 0; private touchYOld?: number = 0; private touchYNew?: number = 0; @@ -82,14 +82,13 @@ export struct PullToRefresh { private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Up | PanDirection.Down }) aboutToAppear() { - if (!this.refreshConfigurator) { - this.refreshConfigurator = new PullToRefreshConfigurator(); - } + // if (!this.refreshConfigurator) { + // this.refreshConfigurator = new PullToRefreshConfigurator(); + // } } private initCanvas(): void { if (this.refreshRingOx == 0) { - if (this.canvasRefresh !== undefined && this.refreshConfigurator !== undefined) { this.canvasRefresh.strokeStyle = this.refreshConfigurator.getRefreshColor(); this.canvasRefresh.fillStyle = this.refreshConfigurator.getRefreshColor(); diff --git a/oh-package.json5 b/oh-package.json5 index 2ce6eb6..499c3d7 100644 --- a/oh-package.json5 +++ b/oh-package.json5 @@ -6,6 +6,6 @@ "name": "pulltorefresh", "description": "example description", "repository": {}, - "version": "2.0.6-rc.0", + "version": "2.1.0", "dependencies": {} } -- Gitee