HarmonyOS NEXT星河版之自定义List下拉刷新与加载更多

文章目录

一、加载更多

借助ListonReachEnd方法,实现加载更多功能,效果如下:

ts 复制代码
@Component
export struct HPList {
  // 数据源
  @Prop dataSource: object[] = []
  // 加载更多是否ing
  @State isLoadingMore: boolean = false
  // 是否还有更多
  @Prop hasMore: boolean = false
  // 渲染Item
  @BuilderParam renderItem: (item: object) => void
  // 加载更多回调
  onLoadMore: () => void = () => {
  }
  // 加载更多文案
  loadingMoreText: string = '加载中...'
  // 没有更多文案
  noMoreDataText: string = '没有更多啦'

  @Builder
  getLoadMoreView() {
    Row() {
      if (!this.hasMore) {
        Text(this.noMoreDataText)
          .fontSize(14)
          .fontColor($r('app.color.text_secondary'))
      } else {
        Row({ space: 8 }) {
          LoadingProgress()
            .width(30)
            .height(30)
            .color(Color.Orange)
          Text(this.loadingMoreText)
            .fontSize(14)
            .fontColor($r('app.color.text_secondary'))
        }
      }
    }
    .height(60)
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }

  build() {
    List() {
      ForEach(this.dataSource, (item: object) => {
        ListItem() {
          if (this.renderItem) {
            this.renderItem(item)
          }
        }
      })
      // 加载更多view
      ListItem() {
        this.getLoadMoreView()
      }
    }
    .onReachEnd(async () => {
      if (!this.isLoadingMore && this.hasMore) {
        this.isLoadingMore = true
        await this.onLoadMore()
        this.isLoadingMore = false
      }
    })
  }
}

使用:

ts 复制代码
import { HPList } from '@hp/basic'
import { promptAction } from '@kit.ArkUI'

@Preview
@Component
export struct Task {
  // 模拟数据
  @State dataList: Person[] = [{
    name: '1'
  }, {
    name: '2'
  }, {
    name: '3'
  }, {
    name: '4'
  }, {
    name: '5'
  }, {
    name: '6'
  }, {
    name: '7'
  }, {
    name: '8'
  }, {
    name: '9'
  }, {
    name: '10'
  }, {
    name: '11'
  }, {
    name: '12'
  }]
  @State hasMore: boolean = true
  isFirstIn: boolean = true

  @Builder
  renderItem(item: object) {
    Row() {
      Text(JSON.stringify(item))
        .fontSize(16)
        .textAlign(TextAlign.Center)
    }
    .width('100%')
    .height(80)
    .borderRadius(15)
    .backgroundColor(Color.Pink)
    .justifyContent(FlexAlign.Center)
    .margin({ bottom: 10 })
  }

  /**
   * 加载更多
   */
  async loadMore() {
    // 首次渲染数据为空时,也会调loadMore
    if (this.isFirstIn) {
      this.isFirstIn = false
      return
    }
    await new Promise<void>((resolve, reject) => {
      setTimeout(() => {
        // 模拟数据
        this.dataList = this.dataList.concat(this.dataList.slice(5))
        if (this.dataList.length > 30) {
          this.hasMore = false
        }
        resolve()
      }, 3000)
    });
  }

  build() {
    HPList({
      dataSource: this.dataList,
      hasMore: this.hasMore,
      renderItem: (item: object) => {
        this.renderItem(item)
      },
      onLoadMore: () => {
        this.loadMore()
      }
    })
  }
}

class Person {
  name: string = ''
}

二、下拉刷新

通过Refresh实现下拉刷新,并自定义头部,效果如下:


代码如下:

ts 复制代码
import { promptAction } from '@kit.ArkUI'

@Component
export struct HPList {
  // 数据源
  @Prop dataSource: object[] = []
  // 加载更多是否ing
  @State isLoadingMore: boolean = false
  // 是否还有更多
  @Prop hasMore: boolean = false
  // 渲染Item
  @BuilderParam renderItem: (item: object) => void
  // 加载更多回调
  onLoadMore: () => void = () => {
  }
  // 加载更多文案
  loadingMoreText: string = '加载中...'
  // 没有更多文案
  noMoreDataText: string = '没有更多啦'
  // 是否下拉刷新ing
  @State isRefreshing: boolean = false
  // 下拉刷新回调
  onRefresh: () => void = () => {
  }
  @State refreshState: RefreshStatus = RefreshStatus.Inactive

  // 获取下拉文本
  getStatusText() {
    switch (this.refreshState) {
      case RefreshStatus.Inactive:
        return ""
      case RefreshStatus.Drag:
        return "继续下拉"
      case RefreshStatus.OverDrag:
        return "松开刷新"
      case RefreshStatus.Refresh:
        return "加载中"
    }
    return ""
  }

  @Builder
  getRefreshView() {
    Row({ space: 10 }) {
      LoadingProgress()
        .color($r('app.color.primary'))
        .width(40)
        .height(40)
      Text(this.getStatusText())
        .fontColor($r('app.color.text_secondary'))
        .fontSize(14)
    }
    .justifyContent(FlexAlign.Center)
    .height(50)
    .width('100%')
  }

  @Builder
  getLoadMoreView() {
    Row() {
      if (!this.hasMore) {
        Text(this.noMoreDataText)
          .fontSize(14)
          .fontColor($r('app.color.text_secondary'))
      } else {
        Row({ space: 8 }) {
          LoadingProgress()
            .width(30)
            .height(30)
            .color(Color.Orange)
          Text(this.loadingMoreText)
            .fontSize(14)
            .fontColor($r('app.color.text_secondary'))
        }
      }
    }
    .height(60)
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }

  build() {
    Refresh({ refreshing: $$this.isRefreshing, builder: this.getRefreshView() }) {
      List() {
        ForEach(this.dataSource, (item: object) => {
          ListItem() {
            if (this.renderItem) {
              this.renderItem(item)
            }
          }
        })
        // 加载更多view
        ListItem() {
          this.getLoadMoreView()
        }
      }
      .onReachEnd(async () => {
        if (!this.isLoadingMore && this.hasMore) {
          this.isLoadingMore = true
          await this.onLoadMore()
          this.isLoadingMore = false
        }
      })
    }
    .onStateChange(async (state) => {
      this.refreshState = state
      if (state === RefreshStatus.Refresh) {
        await this.onRefresh()
        this.isRefreshing = false
      }
    })

  }
}

使用:

ts 复制代码
import { HPList } from '@hp/basic'
import { promptAction } from '@kit.ArkUI'

@Preview
@Component
export struct Task {
  // 模拟数据
  @State dataList: Person[] = [{
    name: '1'
  }, {
    name: '2'
  }, {
    name: '3'
  }, {
    name: '4'
  }, {
    name: '5'
  }, {
    name: '6'
  }, {
    name: '7'
  }, {
    name: '8'
  }, {
    name: '9'
  }, {
    name: '10'
  }, {
    name: '11'
  }, {
    name: '12'
  }]
  @State hasMore: boolean = true
  isFirstIn: boolean = true

  @Builder
  renderItem(item: object) {
    Row() {
      Text(JSON.stringify(item))
        .fontSize(16)
        .textAlign(TextAlign.Center)
    }
    .width('100%')
    .height(80)
    .borderRadius(15)
    .backgroundColor(Color.Pink)
    .justifyContent(FlexAlign.Center)
    .margin({ bottom: 10 })
  }

  async onRefresh() {
    await new Promise<void>((resolve, reject) => {
      setTimeout(() => {
        this.dataList = [{
          name: '旺财'
        },
          {
            name: '张三'
          }, {
            name: '李四'
          }, {
            name: '王五'
          },
          {
            name: '张三1'
          }, {
            name: '李四1'
          }, {
            name: '王五1'
          },
          {
            name: '张三2'
          }, {
            name: '李四2'
          }, {
            name: '王五2'
          }]
        resolve()
      }, 3000)
    });
  }

  /**
   * 加载更多
   */
  async loadMore() {
    // 首次渲染数据为空时,也会调loadMore
    if (this.isFirstIn) {
      this.isFirstIn = false
      return
    }
    promptAction.showToast({ message: 'opppp' })
    await new Promise<void>((resolve, reject) => {
      setTimeout(() => {
        // 模拟数据
        this.dataList = this.dataList.concat(this.dataList.slice(5))
        if (this.dataList.length > 30) {
          this.hasMore = false
        }
        resolve()
      }, 3000)
    });
  }

  build() {
    HPList({
      dataSource: this.dataList,
      hasMore: this.hasMore,
      renderItem: (item: object) => {
        this.renderItem(item)
      },
      onLoadMore:async  () => {
        await this.loadMore()
      },
      onRefresh: async () => {
        await this.onRefresh()
      }
    })
  }
}

class Person {
  name: string = ''
}

三、小结

  • 下拉刷新Refresh及自定义组件
  • 加载更多及自定义组件
相关推荐
见未见过的风景2 天前
将三个list往一个excel表的三个sheet中写入,能用多线程提高写入速度
数据结构·list·excel
殇淋狱陌2 天前
第四章 列表(List)&元组(Tuple)以及代码格式基础语法及操作
数据结构·python·数据分析·list·元组
殇淋狱陌3 天前
第三章 列表(List)语法讲解
数据结构·python·学习·数据分析·list
CURRY30_HJH3 天前
List直接使用removeAll报错
windows·python·list
寒冰的暖4 天前
【C#】List求并集、交集、差集
c#·list
time_silence4 天前
List;Set;Map集合
数据结构·list
梦幻通灵4 天前
Java字符串的|分隔符转List实现方案
java·windows·list
小娄写码4 天前
JAVA集合-LIST 及源码解析
java·开发语言·list
越甲八千5 天前
深入理解STL list erase
开发语言·c++·list
快乐点吧6 天前
【前端面试】list转树、拍平, 指标,
前端·面试·list