文档管理中心
您当前浏览的HarmonyOS 5.0.2(API 14)文档归档不再维护,推荐您使用最新版本。详细请参考文档维护策略变更
API参考应用框架ArkUI(方舟UI框架)ArkTS组件滚动与滑动Refresh

Refresh

可以进行页面下拉操作并显示刷新动效的容器组件。

说明
  • 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。

  • 该组件从API Version 12开始支持与垂直滚动的Swiper和Web的联动。当Swiper设置loop属性为true时,Refresh无法和Swiper产生联动。

子组件

支持单个子组件。

从API version 11开始,Refresh子组件会跟随手势下拉而下移。

接口

Refresh(value: RefreshOptions)

元服务API: 从API version 11开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
value RefreshOptions 刷新组件参数。

RefreshOptions对象说明

系统能力: SystemCapability.ArkUI.ArkUI.Full

展开
名称 类型 必填 说明
refreshing boolean

组件当前是否处于刷新中状态。true表示处于刷新中状态,false表示未处于刷新中状态。

默认值:false

该参数支持$$双向绑定变量。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

offset(deprecated) number | string

下拉起点距离组件顶部的距离。

默认值:16,单位vp

从API version 11开始废弃,无替代接口。

说明:

offset取值范围[0vp,64vp]。大于64vp按照64vp处理。不支持百分比,不支持负数 。

friction(deprecated) number | string

下拉摩擦系数,取值范围为0到100。

默认值:62

- 0表示下拉刷新容器不跟随手势下拉而下拉。

- 100表示下拉刷新容器紧紧跟随手势下拉而下拉。

- 数值越大,下拉刷新容器跟随手势下拉的反应越灵敏。

从API version 11开始废弃,从API version 12开始,可用pullDownRatio属性替代。

builder10+ CustomBuilder

自定义刷新区域显示内容。

说明:

API version 10及之前版本,自定义组件的高度限制在64vp之内。API version 11及以后版本没有此限制。

自定义组件设置了固定高度时,自定义组件会以固定高度显示在刷新区域下方;自定义组件未设置高度时,自定义组件高度会自适应刷新区域高度,会发生自定义组件高度跟随刷新区域变化至0的现象。建议对自定义组件设置最小高度约束来避免自定义组件高度小于预期的情况发生,具体可参照示例3

从API version 12开始,建议使用refreshingContent参数替代builder参数自定义刷新区域显示内容,以避免刷新过程中因自定义组件销毁重建造成的动画中断问题。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

promptText12+ ResourceStr

设置刷新区域底部显示的自定义文本。

说明:

输入文本的限制参考Text组件,使用builder或refreshingContent参数自定义刷新区域显示内容时,promptText不显示。

promptText设置有效时,refreshOffset属性默认值为96vp。

自定义文本最大的字体缩放倍数maxFontScale为2。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

refreshingContent12+ ComponentContent

自定义刷新区域显示内容。

说明:

与builder参数同时设置时builder参数不生效。

自定义组件设置了固定高度时,自定义组件会以固定高度显示在刷新区域下方;自定义组件未设置高度时,自定义组件高度会自适应刷新区域高度,会发生自定义组件高度跟随刷新区域变化至0的现象。建议对自定义组件设置最小高度约束来避免自定义组件高度小于预期的情况发生,具体可参照示例4

元服务API: 从API version 12开始,该接口支持在元服务中使用。

说明
  • 当未设置builder或refreshingContent时,是通过更新子组件的translate属性实现的下拉位移效果,下拉位移过程中不会触发子组件的onAreaChange事件,子组件设置translate属性时不会生效。
  • 当设置了builder或refreshingContent时,是通过更新子组件相对于Refresh组件的位置实现的下拉位移效果,下拉位移过程中可以触发子组件的onAreaChange事件,子组件设置position属性时会固定子组件相对于Refresh组件的位置导致子组件不会跟手进行下拉位移。

属性

支持通用属性外,还支持以下属性:

refreshOffset12+

refreshOffset(value: number)

设置触发刷新的下拉偏移量,当下拉距离小于该属性设置值时离手不会触发刷新。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
value number

下拉偏移量,单位vp。

默认值:未设置promptText参数时为64vp,设置了promptText参数时为96vp。

如果取值为0或负数的时候此接口采用默认值。

pullToRefresh12+

pullToRefresh(value: boolean)

设置当下拉距离超过refreshOffset时是否能触发刷新。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
value boolean

当下拉距离超过refreshOffset时是否能触发刷新。true表示能触发刷新,false表示不能触发刷新。

默认值:true

pullDownRatio12+

pullDownRatio(ratio: Optional<number>)

设置下拉跟手系数。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
ratio Optional<number>

下拉跟手系数。数值越大,跟随手势下拉的反应越灵敏。0表示不跟随手势下拉,1表示等比例跟随手势下拉。

没有设置或设置为undefined时,默认使用动态下拉跟手系数,下拉距离越大,跟手系数越小。

有效值为0-1之间的值,小于0的值会被视为0,大于1的值会被视为1。

事件

除支持通用事件外,还支持以下事件:

onStateChange

onStateChange(callback: (state: RefreshStatus) => void)

当前刷新状态变更时,触发回调。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
state RefreshStatus 刷新状态。

onRefreshing

onRefreshing(callback: () => void)

进入刷新状态时触发回调。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

onOffsetChange12+

onOffsetChange(callback: Callback<number>)

下拉距离发生变化时触发回调。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
callback Callback<number>

下拉距离。

单位:vp

RefreshStatus枚举说明

元服务API: 从API version 11开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

展开
名称 说明
Inactive 0 默认未下拉状态。
Drag 1 下拉中,下拉距离小于刷新距离。
OverDrag 2 下拉中,下拉距离超过刷新距离。
Refresh 3 下拉结束,回弹至刷新距离,进入刷新中状态。
Done 4 刷新结束,返回初始状态(顶部)。

示例

示例1(默认刷新样式)

刷新区域使用默认刷新样式。

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. @Entry
  3. @Component
  4. struct RefreshExample {
  5. @State isRefreshing: boolean = false
  6. @State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
  7. build() {
  8. Column() {
  9. Refresh({ refreshing: $$this.isRefreshing }) {
  10. List() {
  11. ForEach(this.arr, (item: string) => {
  12. ListItem() {
  13. Text('' + item)
  14. .width('70%')
  15. .height(80)
  16. .fontSize(16)
  17. .margin(10)
  18. .textAlign(TextAlign.Center)
  19. .borderRadius(10)
  20. .backgroundColor(0xFFFFFF)
  21. }
  22. }, (item: string) => item)
  23. }
  24. .onScrollIndex((first: number) => {
  25. console.info(first.toString())
  26. })
  27. .width('100%')
  28. .height('100%')
  29. .alignListItem(ListItemAlign.Center)
  30. .scrollBar(BarState.Off)
  31. }
  32. .onStateChange((refreshStatus: RefreshStatus) => {
  33. console.info('Refresh onStatueChange state is ' + refreshStatus)
  34. })
  35. .onOffsetChange((value: number) => {
  36. console.info('Refresh onOffsetChange offset:' + value)
  37. })
  38. .onRefreshing(() => {
  39. setTimeout(() => {
  40. this.isRefreshing = false
  41. }, 2000)
  42. console.log('onRefreshing test')
  43. })
  44. .backgroundColor(0x89CFF0)
  45. .refreshOffset(64)
  46. .pullToRefresh(true)
  47. }
  48. }
  49. }

示例2(设置刷新区域显示文本)

通过promptText参数设置刷新区域显示文本。

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. @Entry
  3. @Component
  4. struct RefreshExample {
  5. @State isRefreshing: boolean = false
  6. @State promptText: string = "Refreshing..."
  7. @State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
  8. build() {
  9. Column() {
  10. Refresh({ refreshing: $$this.isRefreshing, promptText: this.promptText }) {
  11. List() {
  12. ForEach(this.arr, (item: string) => {
  13. ListItem() {
  14. Text('' + item)
  15. .width('70%')
  16. .height(80)
  17. .fontSize(16)
  18. .margin(10)
  19. .textAlign(TextAlign.Center)
  20. .borderRadius(10)
  21. .backgroundColor(0xFFFFFF)
  22. }
  23. }, (item: string) => item)
  24. }
  25. .onScrollIndex((first: number) => {
  26. console.info(first.toString())
  27. })
  28. .width('100%')
  29. .height('100%')
  30. .alignListItem(ListItemAlign.Center)
  31. .scrollBar(BarState.Off)
  32. }
  33. .backgroundColor(0x89CFF0)
  34. .pullToRefresh(true)
  35. .refreshOffset(96)
  36. .onStateChange((refreshStatus: RefreshStatus) => {
  37. console.info('Refresh onStatueChange state is ' + refreshStatus)
  38. })
  39. .onOffsetChange((value: number) => {
  40. console.info('Refresh onOffsetChange offset:' + value)
  41. })
  42. .onRefreshing(() => {
  43. setTimeout(() => {
  44. this.isRefreshing = false
  45. }, 2000)
  46. console.log('onRefreshing test')
  47. })
  48. }
  49. }
  50. }

示例3(自定义刷新区域显示内容-builder)

通过builder参数自定义刷新区域显示内容。

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. @Entry
  3. @Component
  4. struct RefreshExample {
  5. @State isRefreshing: boolean = false
  6. @State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
  7. @Builder
  8. customRefreshComponent() {
  9. Stack() {
  10. Row() {
  11. LoadingProgress().height(32)
  12. Text("Refreshing...").fontSize(16).margin({ left: 20 })
  13. }
  14. .alignItems(VerticalAlign.Center)
  15. }
  16. .align(Alignment.Center)
  17. .clip(true)
  18. // 设置最小高度约束保证自定义组件高度随刷新区域高度变化时自定义组件高度不会低于minHeight
  19. .constraintSize({ minHeight: 32 })
  20. .width("100%")
  21. }
  22. build() {
  23. Column() {
  24. Refresh({ refreshing: $$this.isRefreshing, builder: this.customRefreshComponent() }) {
  25. List() {
  26. ForEach(this.arr, (item: string) => {
  27. ListItem() {
  28. Text('' + item)
  29. .width('70%')
  30. .height(80)
  31. .fontSize(16)
  32. .margin(10)
  33. .textAlign(TextAlign.Center)
  34. .borderRadius(10)
  35. .backgroundColor(0xFFFFFF)
  36. }
  37. }, (item: string) => item)
  38. }
  39. .onScrollIndex((first: number) => {
  40. console.info(first.toString())
  41. })
  42. .width('100%')
  43. .height('100%')
  44. .alignListItem(ListItemAlign.Center)
  45. .scrollBar(BarState.Off)
  46. }
  47. .backgroundColor(0x89CFF0)
  48. .pullToRefresh(true)
  49. .refreshOffset(64)
  50. .onStateChange((refreshStatus: RefreshStatus) => {
  51. console.info('Refresh onStatueChange state is ' + refreshStatus)
  52. })
  53. .onRefreshing(() => {
  54. setTimeout(() => {
  55. this.isRefreshing = false
  56. }, 2000)
  57. console.log('onRefreshing test')
  58. })
  59. }
  60. }
  61. }

示例4(自定义刷新区域显示内容-refreshingContent)

通过refreshingContent参数自定义刷新区域显示内容。

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. import { ComponentContent } from '@ohos.arkui.node';
  3. class Params {
  4. refreshStatus: RefreshStatus = RefreshStatus.Inactive
  5. constructor(refreshStatus: RefreshStatus) {
  6. this.refreshStatus = refreshStatus;
  7. }
  8. }
  9. @Builder
  10. function customRefreshingContent(params: Params) {
  11. Stack() {
  12. Row() {
  13. LoadingProgress().height(32)
  14. Text("refreshStatus: " + params.refreshStatus).fontSize(16).margin({ left: 20 })
  15. }
  16. .alignItems(VerticalAlign.Center)
  17. }
  18. .align(Alignment.Center)
  19. .clip(true)
  20. // 设置最小高度约束保证自定义组件高度随刷新区域高度变化时自定义组件高度不会低于minHeight
  21. .constraintSize({ minHeight: 32 })
  22. .width("100%")
  23. }
  24. @Entry
  25. @Component
  26. struct RefreshExample {
  27. @State isRefreshing: boolean = false
  28. @State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
  29. @State refreshStatus: RefreshStatus = RefreshStatus.Inactive
  30. private contentNode?: ComponentContent<Object> = undefined
  31. private params: Params = new Params(RefreshStatus.Inactive)
  32. aboutToAppear(): void {
  33. let uiContext = this.getUIContext()
  34. this.contentNode = new ComponentContent(uiContext, wrapBuilder(customRefreshingContent), this.params)
  35. }
  36. build() {
  37. Column() {
  38. Refresh({ refreshing: $$this.isRefreshing, refreshingContent: this.contentNode }) {
  39. List() {
  40. ForEach(this.arr, (item: string) => {
  41. ListItem() {
  42. Text('' + item)
  43. .width('70%')
  44. .height(80)
  45. .fontSize(16)
  46. .margin(10)
  47. .textAlign(TextAlign.Center)
  48. .borderRadius(10)
  49. .backgroundColor(0xFFFFFF)
  50. }
  51. }, (item: string) => item)
  52. }
  53. .onScrollIndex((first: number) => {
  54. console.info(first.toString())
  55. })
  56. .width('100%')
  57. .height('100%')
  58. .alignListItem(ListItemAlign.Center)
  59. .scrollBar(BarState.Off)
  60. }
  61. .backgroundColor(0x89CFF0)
  62. .pullToRefresh(true)
  63. .refreshOffset(96)
  64. .onStateChange((refreshStatus: RefreshStatus) => {
  65. this.refreshStatus = refreshStatus
  66. this.params.refreshStatus = refreshStatus
  67. // 更新自定义组件内容
  68. this.contentNode?.update(this.params)
  69. console.info('Refresh onStatueChange state is ' + refreshStatus)
  70. })
  71. .onRefreshing(() => {
  72. setTimeout(() => {
  73. this.isRefreshing = false
  74. }, 2000)
  75. console.log('onRefreshing test')
  76. })
  77. }
  78. }
  79. }

示例5(实现最大下拉距离)

通过pullDownRatio属性和onOffsetChange事件实现最大下拉距离。

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. import { ComponentContent } from '@ohos.arkui.node';
  3. @Builder
  4. function customRefreshingContent() {
  5. Stack() {
  6. Row() {
  7. LoadingProgress().height(32)
  8. }
  9. .alignItems(VerticalAlign.Center)
  10. }
  11. .align(Alignment.Center)
  12. .clip(true)
  13. // 设置最小高度约束保证自定义组件高度随刷新区域高度变化时自定义组件高度不会低于minHeight
  14. .constraintSize({ minHeight: 32 })
  15. .width("100%")
  16. }
  17. @Entry
  18. @Component
  19. struct RefreshExample {
  20. @State isRefreshing: boolean = false
  21. @State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
  22. @State maxRefreshingHeight: number = 100.0
  23. @State ratio: number = 1
  24. private contentNode?: ComponentContent<Object> = undefined
  25. aboutToAppear(): void {
  26. let uiContext = this.getUIContext();
  27. this.contentNode = new ComponentContent(uiContext, wrapBuilder(customRefreshingContent))
  28. }
  29. build() {
  30. Column() {
  31. Refresh({ refreshing: $$this.isRefreshing, refreshingContent: this.contentNode }) {
  32. List() {
  33. ForEach(this.arr, (item: string) => {
  34. ListItem() {
  35. Text('' + item)
  36. .width('70%')
  37. .height(80)
  38. .fontSize(16)
  39. .margin(10)
  40. .textAlign(TextAlign.Center)
  41. .borderRadius(10)
  42. .backgroundColor(0xFFFFFF)
  43. }
  44. }, (item: string) => item)
  45. }
  46. .onScrollIndex((first: number) => {
  47. console.info(first.toString())
  48. })
  49. .width('100%')
  50. .height('100%')
  51. .alignListItem(ListItemAlign.Center)
  52. .scrollBar(BarState.Off)
  53. }
  54. .backgroundColor(0x89CFF0)
  55. .pullDownRatio(this.ratio)
  56. .pullToRefresh(true)
  57. .refreshOffset(64)
  58. .onOffsetChange((offset: number) => {
  59. // 越接近最大距离,下拉跟手系数越小
  60. this.ratio = 1 - Math.pow((offset / this.maxRefreshingHeight), 3)
  61. })
  62. .onStateChange((refreshStatus: RefreshStatus) => {
  63. console.info('Refresh onStatueChange state is ' + refreshStatus)
  64. })
  65. .onRefreshing(() => {
  66. setTimeout(() => {
  67. this.isRefreshing = false
  68. }, 2000)
  69. console.log('onRefreshing test')
  70. })
  71. }
  72. }
  73. }

示例6(实现下拉刷新上拉加载更多)

Refresh组件与List组件组合实现下拉刷新上拉加载更多效果。

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. @Entry
  3. @Component
  4. struct ListRefreshLoad {
  5. @State arr: Array<number> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  6. @State refreshing: boolean = false;
  7. @State refreshOffset: number = 0;
  8. @State refreshState: RefreshStatus = RefreshStatus.Inactive;
  9. @State canLoad: boolean = false;
  10. @State isLoading: boolean = false;
  11. @Builder
  12. refreshBuilder() {
  13. Stack({ alignContent: Alignment.Bottom }) {
  14. // 可以通过刷新状态控制是否存在Progress组件
  15. // 当刷新状态处于下拉中或刷新中状态时Progress组件才存在
  16. if (this.refreshState != RefreshStatus.Inactive && this.refreshState != RefreshStatus.Done) {
  17. Progress({ value: this.refreshOffset, total: 64, type: ProgressType.Ring })
  18. .width(32).height(32)
  19. .style({ status: this.refreshing ? ProgressStatus.LOADING : ProgressStatus.PROGRESSING })
  20. .margin(10)
  21. }
  22. }
  23. .clip(true)
  24. .height("100%")
  25. .width("100%")
  26. }
  27. @Builder
  28. footer() {
  29. Row() {
  30. LoadingProgress().height(32).width(48)
  31. Text("加载中")
  32. }.width("100%")
  33. .height(64)
  34. .justifyContent(FlexAlign.Center)
  35. // 当不处于加载中状态时隐藏组件
  36. .visibility(this.isLoading ? Visibility.Visible : Visibility.Hidden)
  37. }
  38. build() {
  39. Refresh({ refreshing: $$this.refreshing, builder: this.refreshBuilder() }) {
  40. List() {
  41. ForEach(this.arr, (item: number) => {
  42. ListItem() {
  43. Text('' + item)
  44. .width('100%')
  45. .height(80)
  46. .fontSize(16)
  47. .textAlign(TextAlign.Center)
  48. .backgroundColor(0xFFFFFF)
  49. }.borderWidth(1)
  50. }, (item: string) => item)
  51. ListItem() {
  52. this.footer();
  53. }
  54. }
  55. .onScrollIndex((start: number, end: number) => {
  56. // 当达到列表末尾时,触发新数据加载
  57. if (this.canLoad && end >= this.arr.length - 1) {
  58. this.canLoad = false;
  59. this.isLoading = true;
  60. // 模拟新数据加载
  61. setTimeout(() => {
  62. for (let i = 0; i < 10; i++) {
  63. this.arr.push(this.arr.length);
  64. this.isLoading = false;
  65. }
  66. }, 700)
  67. }
  68. })
  69. .onScrollFrameBegin((offset: number, state: ScrollState) => {
  70. // 只有当向上滑动时触发新数据加载
  71. if (offset > 5 && !this.isLoading) {
  72. this.canLoad = true;
  73. }
  74. return { offsetRemain: offset };
  75. })
  76. .scrollBar(BarState.Off)
  77. // 开启边缘滑动效果
  78. .edgeEffect(EdgeEffect.Spring, { alwaysEnabled: true })
  79. }
  80. .width('100%')
  81. .height('100%')
  82. .backgroundColor(0xDCDCDC)
  83. .onOffsetChange((offset: number) => {
  84. this.refreshOffset = offset;
  85. })
  86. .onStateChange((state: RefreshStatus) => {
  87. this.refreshState = state;
  88. })
  89. .onRefreshing(() => {
  90. // 模拟数据刷新
  91. setTimeout(() => {
  92. this.refreshing = false;
  93. }, 2000)
  94. })
  95. }
  96. }

在 API参考 中进行搜索
请输入您想要搜索的关键词