【高心星出品】
下拉刷新组件Refresh
Refresh是可以进行页面下拉操作并显示刷新动效的容器组件,包含刷新头和内容展示区,在下拉中可以获取刷新的状态来动态展示刷新头的效果。可以与SwipeRefresher组件联用。
组件结构
Refresh({ refreshing: $$this.isrefreshing,builder:this.combuilder() }) { //刷新控制变量和自定义刷新头
List() {
ForEach(this.datas, (item: string) => {
ListItem() {
.... //子布局
}
}, (item: string) => JSON.stringify(item))
}.width('100%').height('100%')
.onScrollIndex((start: number, end: number, center: number) => {
if (end == this.datas.length - 1) {//当显示最后一个item的时候
//上拉加载更多
}
})
}.width('100%').height('100%')
.onRefreshing(() => {
//下拉刷新逻辑
})
注意: 刷新控制变量必须要加上$$实现双向绑定,否则无法使用控制变量来控制刷新状态。
简单应用
代码逻辑:
import { LoadingDialog, promptAction } from '@kit.ArkUI';
@Entry
@Component
struct Refreshpage {
@State message: string = 'Hello World';
//刷新控变量
@State isrefreshing: boolean = false
//初数据源
@State odatas: string[] = ['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7', 'item8', 'item9', 'item10']
//添加数据
@State extradatas: string[] = ['extra1', 'extra2', 'extra3', 'extra4', 'extra5', 'extra6']
//新数据源
@State ndatas: string[] =
['item11', 'item12', 'item13', 'item14', 'item15', 'item16', 'item17', 'item18', 'item19', 'item20']
//加载更多对话框
private dialogcontroller: CustomDialogController =
new CustomDialogController({ builder: LoadingDialog({ content: '加载中...' }) })
build() {
Column() {
Refresh({ refreshing: $$this.isrefreshing }) {//采用双向绑定控制器
List() {
ForEach(this.odatas, (item: string) => {
ListItem() {
Text(item)
.fontSize(24)
.border({ width: 2, color: Color.Gray, style: BorderStyle.Dotted })
.width('100%')
.textAlign(TextAlign.Center)
.padding(30)
}
},)//模拟数据 使用默认键生成器
}.width('100%').height('100%')
.onScrollIndex((start: number, end: number, center: number) => {
console.log('gxxt ', 'end=' + end, ' len=' + this.odatas.length)
if (end == this.odatas.length - 1) {//加载更多
this.dialogcontroller.open()//弹窗
setTimeout(() => {
this.odatas.push(...this.extradatas) //添加数据
this.dialogcontroller.close() //关闭窗口
}, 2000)
}
})
}.width('100%').height('100%')
.onRefreshing(() => {//下拉刷新
setTimeout(() => {
this.odatas = this.ndatas //更新数据源
this.isrefreshing = false //修改刷新状态
}, 2000)
})
}
.height('100%')
.width('100%')
}
}
自定义刷新头
使用swipeRefresh构建刷新头
构建函数:
@Builder genrefresh(){//构建刷新头
Column(){
SwipeRefresher({content:'刷新中...',isLoading:true})
}.padding(20)
}
核心代码:
Refresh({ refreshing: $$this.isrefreshing,builder:this.genrefresh() }) {//使用自定义刷新头
List() {
ForEach(this.odatas, (item: string) => {
ListItem() {
Text(item)
.fontSize(24)
.border({ width: 2, color: Color.Gray, style: BorderStyle.Dotted })
.width('100%')
.textAlign(TextAlign.Center)
.padding(30)
}
},)
}.width('100%').height('100%')
.onScrollIndex((start: number, end: number, center: number) => {
console.log('gxxt ', 'end=' + end, ' len=' + this.odatas.length)
if (end == this.odatas.length - 1) {
this.dialogcontroller.open()
setTimeout(() => {
this.odatas.push(...this.extradatas)
this.dialogcontroller.close()
}, 2000)
}
})
}.width('100%').height('100%')
.onRefreshing(() => {
setTimeout(() => {
this.odatas = this.ndatas
this.isrefreshing = false
}, 2000)
})
自定义加载更多布局
构建加载布局
这里使用一个进度条配合文字显示,其中进度条状态为loading。
@Builder footer(){//加载布局
Row(){
Progress({value:10,type:ProgressType.Ring}).style({status:ProgressStatus.LOADING}).color(Color.Black).width(45)
Text('加载中...').fontSize(20).margin({left:20})
}.width('100%').padding(20).backgroundColor(Color.Gray).justifyContent(FlexAlign.Center)
.visibility(this.isloading?Visibility.Visible:Visibility.Hidden)
}
完整代码:
import { SwipeRefresher } from '@kit.ArkUI';
@Entry
@Component
struct Refreshpage {
//刷新控制变量
@State isrefreshing: boolean = false
//加载控制变量
@State isloading:boolean=false
//初始数据源
@State odatas: string[] = ['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7', 'item8', 'item9', 'item10']
//新增数据源
@State extradatas: string[] = ['extra1', 'extra2', 'extra3', 'extra4', 'extra5', 'extra6']
//新数据源
@State ndatas: string[] =
['item11', 'item12', 'item13', 'item14', 'item15', 'item16', 'item17', 'item18', 'item19', 'item20']
@Builder genrefresh(){ //自定义刷新头
Column(){
SwipeRefresher({content:'刷新中...',isLoading:true})
}.padding(20)
}
@Builder footer(){//自定义加载布局
Row(){
Progress({value:10,type:ProgressType.Ring}).style({status:ProgressStatus.LOADING}).color(Color.Black).width(45)
Text('加载中...').fontSize(20).margin({left:20})
}.width('100%').padding(20).backgroundColor(Color.Gray).justifyContent(FlexAlign.Center)
.visibility(this.isloading?Visibility.Visible:Visibility.Hidden) //根据加载状态变量控制加载布局是否显示
}
build() {
Column() {
Refresh({ refreshing: $$this.isrefreshing,builder:this.genrefresh() }) {
List() {
ForEach(this.odatas, (item: string) => {
ListItem() {
Text(item)
.fontSize(24)
.border({ width: 2, color: Color.Gray, style: BorderStyle.Dotted })
.width('100%')
.textAlign(TextAlign.Center)
.padding(30)
}
},)
ListItem(){//末尾增加加载布局
this.footer()
}
}.width('100%').height('100%')
.onScrollIndex((start: number, end: number, center: number) => {
if (end == this.odatas.length) {//由于末尾有个加载布局要控制一下end值
this.isloading=true //开启加载布局
setTimeout(() => {
this.odatas.push(...this.extradatas)
this.isloading=false //关闭加载布局
}, 2000)
}
})
}.width('100%').height('100%')
.onRefreshing(() => {
setTimeout(() => {
this.odatas = this.ndatas//更新数据
this.isrefreshing = false//关闭刷新头
}, 2000)
})
}
.height('100%')
.width('100%')
}
}