风雨同行 发表于 2024-6-21 13:15:31

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

一、加载更多

借助List的onReachEnd方法,实现加载更多功能,结果如下:
https://img-blog.csdnimg.cn/direct/5384ecbc74184d7a947373d85615c486.png
https://img-blog.csdnimg.cn/direct/a4042df7dece43d98a606c5600db2675.png

@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
      }
    })
}
}
使用:
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实现下拉革新,并自定义头部,结果如下:
https://img-blog.csdnimg.cn/direct/69fa4ff2c571486a9021b0eb527f99a6.png
https://img-blog.csdnimg.cn/direct/60c6646f94fa4cb9b37934e4258ba0e4.png
https://img-blog.csdnimg.cn/direct/20f87586b7f846c6be943e944ad18154.png
代码如下:
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
      }
    })

}
}
使用:
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及自定义组件
[*]加载更多及自定义组件

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: HarmonyOS NEXT星河版之自定义List下拉革新与加载更多