HarmonyOS数据列表加载更多(无需监听列表滑到最底部)

前言

有数据列表的页面,一般需要使用下拉刷新和上拉加载的功能

而数据列表实现加载下一页的功能,目前有以下几种方案

(如果还有更优雅的方案,欢迎大佬们在评论区补充)

(源码地址在文末)

加载更多方案

  1. 监听列表的滑动事件,在列表滑动到底部时触发加载更多的逻辑
  2. 自定义布局,监听手势,上拉布局到某个高度时->释放手势->触发加载更多的逻辑
    (实现原理上篇文章有说)
  3. 手动给数据列表加个ListItem,然后监听onVisibleAreaChange事件 (本文主要介绍的方案)
  4. LazyForEach中通过index判断是否是最后一个item,然后触发加载更多逻辑
kotlin 复制代码
//在IDataSource中的totalCount方法中返回真实item数量+1
totalCount(): number {
  return this.dataList.length + 1;
}
scss 复制代码
LazyForEach(IDataSource, (item: Object, index) => {
  if(通过index判断是否是最后一个item){
    ListItem() {
      /*footer布局*/
    }
  }else{
    ListItem() {
      /*正常item布局*/
    }
  }
})

各个方案缺点

第1种方案

列表必须滑动到最底部才能触发事件,哪怕列表滑到99%也不能触发。

如果列表有回弹效果,回弹时又会触发一次(小问题,可以通过逻辑判断规避或者禁用回弹效果)

第2种方案

每次都需要一个上拉的操作,用户体验感略差(如果产品明确需要这种交互效果除外)

第4种方案

该方案也是我一开始实现的方案,体验感也是最好的一种

(真正的无感加载,正常滑动列表时,还没看到footer布局时,下一页可能就加载完成了)

但是因为实现逻辑不够优雅,被我放弃了,然后改用第3种方案实现(对已有布局没有入侵性)

效果图

垂直列表
下拉刷新+上拉加载 List垂直列表 Grid垂直列表 瀑布流垂直列表
横向列表
List横向列表 Grid横向列表 瀑布流横向列表

第3种方案

实现过程

  1. 在list列表尾部添加一个item布局,然后监听item布局的onVisibleAreaChange事件
  2. onVisibleAreaChange()第一个参数传[0],这样滑动列表时item布局在屏幕显示一丢丢时,就会触发该事件的回调,然后在该事件中执行加载更多的逻辑,
    这样就规避第1种方案中必须滑动到最底部的问题

如果用户滑动速度不是很快,可以做到无感加载下一页

如果产品需要footer视图出现一半及以上的面积,让用户感知明显,再触发加载更多

只需要将第一个参数改成[0.5]即可

javascript 复制代码
List() {
  LazyForEach(this.adapter, (item: Object, index) => {
    ListItem() {
       Text("正常item布局")
    }
  })
  
  /*手动添加一个footer布局*/
  ListItem() {
    LoadMoreView({
      /*控制器,用于通知LoadMoreView内部是否加载完成或加载错误或是否还有更多数据*/
      controller: this.loadMoreController,
      
      loadMore: () => {
        /*触发加载更多*/
      },
      
      /*非必传:是否是垂直列表*/
      vertical: this.isVertical,
      
      /*非必传:加载数据中的自定义视图*/
      loadingView:()=>{},
      
      /*非必传:加载错误的自定义视图*/
      errorView:()=>{},
      
      /*非必传:暂无更多数据的自定义视图*/
      noMoreView:()=>{}
    })
  }
}
typescript 复制代码
@Component
export struct LoadMoreView {
    build() {
      Text("正在加载更多...")
      .width("100%")
      .height("50")
      .onVisibleAreaChange([0], (isVisible: boolean, currentRatio: number) => {
        if (isVisible) {
          /*触发加载更多逻辑*/
        }
      })
    }
}
typescript 复制代码
export class LoadMoreController {
  loadEnd: (hasMore: boolean) => void = (hasMore: boolean) => {
    //请求数据完成,hasMore true:还有更多数据,false:暂无更多数据
  }
  loadError: () => void = () => {
    //请求数据失败
  }
}

项目源码

-->源码地址
gitee.com/zhongrui_de...

(ps:大佬~点个关注吧,后续会发布如何优雅的实现一行代码在任意处实现弹窗的文章)

相关推荐
Eastsea.Chen2 小时前
MTK Android12 user版本MtkLogger
android·framework
Random_index6 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
长亭外的少年9 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
鸿蒙自习室10 小时前
鸿蒙多线程开发——线程间数据通信对象02
ui·harmonyos·鸿蒙
建群新人小猿11 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
SuperHeroWu712 小时前
【HarmonyOS】鸿蒙应用接入微博分享
华为·harmonyos·鸿蒙·微博·微博分享·微博sdk集成·sdk集成
1024小神13 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛13 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法13 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
zhangjr057514 小时前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts