头图

【高心星出品】

下拉刷新组件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%')
  }
}

高心星
1 声望1 粉丝

华为开发者专家(HDE)。 10年教学经验,兼任多家科技公司技术顾问。先后从事JavaEE项目开发、Python爬虫、HarmonyOS移动应用开发等课程的教学工作。参与开发《鸿蒙应用开发基础》和《鸿蒙项目实战》等课程。