一、前言
可以進行頁面下拉操作并顯示刷新動效的容器組件。
說明
- 該組件從API Version 8開始支持。后續版本如有新增內容,則采用上角標單獨標記該內容的起始版本。
- 該組件從API Version 12開始支持與垂直滾動的Swiper和Web的聯動。當Swiper設置loop屬性為true時,Refresh無法和Swiper產生聯動。
二、子組件
支持單個子組件。
從API version 11開始,Refresh子組件會跟隨手勢下拉而下移。
三、接口
Refresh(value: RefreshOptions)
創建Refresh容器。
參數:
參數名 | 類型 | 必填 | 說明 |
---|---|---|---|
value | RefreshOptions | 是 | 刷新組件參數。 |
四、屬性
支持通用屬性外,還支持以下屬性:
refreshOffset12+
refreshOffset(value: number)
設置觸發刷新的下拉偏移量,當下拉距離小于該屬性設置值時離手不會觸發刷新。
參數:
參數名 | 類型 | 必填 | 說明 |
---|---|---|---|
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 |
五、事件
除支持通用事件外,還支持以下事件:
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)
下拉距離發生變化時觸發回調。
元服務API: 從API version 12開始,該接口支持在元服務中使用。
系統能力: SystemCapability.ArkUI.ArkUI.Full
參數
參數名 | 類型 | 必填 | 說明 |
---|---|---|---|
callback | Callback | 是 | 下拉距離。 單位:vp |
RefreshStatus枚舉說明
Refresh刷新狀態枚舉。
元服務API: 從API version 11開始,該接口支持在元服務中使用。
系統能力: SystemCapability.ArkUI.ArkUI.Full
名稱 | 值 | 說明 |
---|---|---|
Inactive | 0 | 默認未下拉狀態。 |
Drag | 1 | 下拉中 |
OverDrag | 2 | 下拉中,下拉距離超過刷新距離。 |
Refresh | 3 | 下拉結束,回彈至刷新距離,進入刷新中狀態。 |
Done | 4 | 刷新結束,返回初始狀態(頂部)。 |
六、示例
6.1 示例(默認刷新樣式)
刷新區域使用默認刷新樣式。效果圖如下
TestRefreshExample1.ets代碼
@Entry
@Component
struct TestRefreshExample1 {@State isRefreshing: boolean = false@State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']build() {Column() {Refresh({ refreshing: $$this.isRefreshing }) {List() {ForEach(this.arr, (item: string) => {ListItem() {Text('' + item).width('70%').height(80).fontSize(16).margin(10).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)}}, (item: string) => item)}.onScrollIndex((first: number) => {console.info(first.toString())}).width('100%').height('100%').alignListItem(ListItemAlign.Center).scrollBar(BarState.Off)}.onStateChange((refreshStatus: RefreshStatus) => {console.info('Refresh onStatueChange state is ' + refreshStatus)}).onOffsetChange((value: number) => {console.info('Refresh onOffsetChange offset:' + value)}).onRefreshing(() => {setTimeout(() => {this.isRefreshing = false}, 2000)console.log('onRefreshing test')}).backgroundColor(0x89CFF0).refreshOffset(64).pullToRefresh(true)}}
}
6.2 示例(設置刷新區域顯示文本)
通過promptText參數設置刷新區域顯示文本。
TestRefreshExample2.ets代碼
@Entry
@Component
struct TestRefreshExample2 {@State isRefreshing: boolean = false@State promptText: string = "Refreshing..."@State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']build() {Column() {Refresh({ refreshing: $$this.isRefreshing, promptText: this.promptText }) {List() {ForEach(this.arr, (item: string) => {ListItem() {Text('' + item).width('70%').height(80).fontSize(16).margin(10).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)}}, (item: string) => item)}.onScrollIndex((first: number) => {console.info(first.toString())}).width('100%').height('100%').alignListItem(ListItemAlign.Center).scrollBar(BarState.Off)}.backgroundColor(0x89CFF0).pullToRefresh(true).refreshOffset(96).onStateChange((refreshStatus: RefreshStatus) => {console.info('Refresh onStatueChange state is ' + refreshStatus)}).onOffsetChange((value: number) => {console.info('Refresh onOffsetChange offset:' + value)}).onRefreshing(() => {setTimeout(() => {this.isRefreshing = false}, 2000)console.log('onRefreshing test')})}}
}
6.3 示例(自定義刷新區域顯示內容-builder)
通過builder參數自定義刷新區域顯示內容。
TestRefreshExample3.ets代碼
@Entry
@Component
struct TestRefreshExample3 {@State isRefreshing: boolean = false@State arr: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']@BuildercustomRefreshComponent() {Stack() {Row() {LoadingProgress().height(32)Text("Refreshing...").fontSize(16).margin({ left: 20 })}.alignItems(VerticalAlign.Center)}.align(Alignment.Center).clip(true)// 設置最小高度約束保證自定義組件高度隨刷新區域高度變化時自定義組件高度不會低于minHeight.constraintSize({ minHeight: 32 }).width("100%")}build() {Column() {Refresh({ refreshing: $$this.isRefreshing, builder: this.customRefreshComponent() }) {List() {ForEach(this.arr, (item: string) => {ListItem() {Text('' + item).width('70%').height(80).fontSize(16).fontColor(Color.Black).textAlign(TextAlign.Center).margin(10).borderRadius(10).backgroundColor(0xFFFFFF)}}, (item: string) => item)}.onScrollIndex((start: number, end: number) => {console.log(`當前滾動的 index start = ${start} end = ${end}`)}).alignListItem(ListItemAlign.Center).scrollBar(BarState.Off)}.backgroundColor(0x89CFF0).pullToRefresh(true) // 設置當下拉距離超過refreshOffset時是否能觸發刷新。true表示能觸發刷新, 默認值:true.refreshOffset(64) // 下拉偏移量,單位vp。默認值:未設置promptText參數時為64vp,設置了promptText參數時為96vp。 如果取值為0或負數的時候此接口采用默認值。.onStateChange((refreshStatus: RefreshStatus) => {console.log(`當前刷新狀態回調 onStatueChange state is ${refreshStatus}`)}).onRefreshing(() => {setTimeout(() => {this.isRefreshing = false;console.log("停止刷新")}, 2000)console.log("onRefreshing 測試")})}}
}
6.4 示例(實現下拉刷新上拉加載更多)
Refresh組件與List組件組合實現下拉刷新上拉加載更多效果。
TestListRefreshLoad.ets代碼
@Entry
@Component
struct TestListRefreshLoad {@State arr: Array<number> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];@State refreshing: boolean = false;@State refreshOffset: number = 0;@State refreshState: RefreshStatus = RefreshStatus.Inactive;@State isLoading: boolean = false;@BuilderrefreshBuilder() {Stack({ alignContent: Alignment.Bottom }) {// 可以通過刷新狀態控制是否存在Progress組件// 當刷新狀態處于下拉中或刷新中狀態時Progress組件才存在if (this.refreshState != RefreshStatus.Inactive && this.refreshState != RefreshStatus.Done) {Progress({ value: this.refreshOffset, total: 64, type: ProgressType.Ring }).width(32).height(32).style({ status: this.refreshing ? ProgressStatus.LOADING : ProgressStatus.PROGRESSING }).margin(10)}}.clip(true).height("100%").width("100%")}@Builderfooter() {Row() {LoadingProgress().height(32).width(48)Text("加載中")}.width("100%").height(64).justifyContent(FlexAlign.Center)// 當不處于加載中狀態時隱藏組件.visibility(this.isLoading ? Visibility.Visible : Visibility.Hidden)}build() {Refresh({ refreshing: $$this.refreshing, builder: this.refreshBuilder() }) {List() {ForEach(this.arr, (item: number) => {ListItem() {Text('' + item).width('100%').height(80).fontSize(16).textAlign(TextAlign.Center).backgroundColor(0xFFFFFF)}.borderWidth(1)}, (item: string) => item)ListItem() {this.footer();}}.onScrollIndex((start: number, end: number) => {// 當達到列表末尾時,觸發新數據加載if (end >= this.arr.length - 1) {this.isLoading = true;// 模擬新數據加載setTimeout(() => {for (let i = 0; i < 10; i++) {this.arr.push(this.arr.length);this.isLoading = false;}}, 700)}}).scrollBar(BarState.Off)// 開啟邊緣滑動效果.edgeEffect(EdgeEffect.Spring, { alwaysEnabled: true })}.width('100%').height('100%').backgroundColor(0xDCDCDC).onOffsetChange((offset: number) => {this.refreshOffset = offset;}).onStateChange((state: RefreshStatus) => {this.refreshState = state;}).onRefreshing(() => {// 模擬數據刷新setTimeout(() => {this.refreshing = false;}, 2000)})}
}