当前位置: 首页 > news >正文

【Flutter】使用ScrollController配合EasyRefresh实现列表预加载:在还未滑动到底部时加载下一页数据

需求/背景

在我们的业务场景中,列表的加载使用easy_refresh组件:

https://pub.dev/packages/easy_refresh

大概效果是往上滑动到一定的offset会触发一个上滑加载,可以触发一些网络请求拉取列表后面的数据来展示。

这种模式一般在一页翻完以后,才会触发加载,此时需要等待加载完以后才能看到新的数据。现在的需求是,想要在即将滑到当前页面底部的时候,预先加载后面的数据,这样表面上看来没有了中间的等待感,可以提升用户体验

思路

首先easy_refresh组件没有提供“预加载”相关的参数,所以我们需要自己去实现。分析需求,我们如何得知触发预加载的这个时机呢?可以比较容易的想到,如果可以监听到滑动的距离,那么就可以根据滑动距离触发加载,比如当监听到用户已经上滑了约一个手机高度那么高(一页)时,触发预加载。

监听滑动的offset,可以联想到使用ScrollController实现。

用法

double _currentOffset = 0; // 记录上一次触发了预加载的位置
ScrollController scrollController; // 列表controller,赋给用于展示元素的ListView
EasyRefreshController refreshController = EasyRefreshController(controlFinishLoad: true, controlFinishRefresh: true); // EasyRefresh组件的controller设置

在对应位置监听scrollController:

scrollController.addListener(() => preLoad());

preLoad方法:

  /// 通过检查当前滑动的位置触发加载.void preLoad() async {if (scrollController.offset - _currentOffset > appHeight) {_currentOffset = scrollController.offset;if (!isNoMore) {await updateItems();  // 加载一页数据}if (isNoMore) refreshController.finishLoad(IndicatorResult.noMore);}}
  • isNoMore:
    判断是否为最后一页,不同的业务场景可能不一样,我是根据拉取的数据数量是否小于我要求的数量来判断的,比如我请求api的时候要拉取20条数据,如果此时返回的不足20条,则说明已经拉到了最后一页。

  • refreshController:
    赋给EasyRefresh组件,这里要finishLoad是因为,在EasyRefresh组件中也有onLoad回调,原本的上拉加载和预加载是同时要有的,为了避免预加载到最后一页,再上滑的时候又发多余的请求,在这里需要及时将加载状态设为IndicatorResult.noMore。

  • appHeight: 屏幕高度,如果项目里面有使用Getx,则计算方式为:

    double appHeight = View.of(Get.context!).physicalSize.height / Get.pixelRatio;
    

    这里使用appHeight作为判断标准,是与业务相关的,这个时候根据我们api的速度等情况,上滑起来比较丝滑:即当往上滑动了一个屏幕这么多的距离时,触发预加载。这个参数可以根据实际情况设置的大一点或小一点。

http://www.lryc.cn/news/518796.html

相关文章:

  • 【2025 Rust学习 --- 11 实用工具特型01】
  • 网络安全基础以及概念
  • windows和linux的抓包方式
  • 【Uniapp-Vue3】v-if条件渲染及v-show的选择对比
  • 宝塔面板使用 GoAccess Web 日志分析教程
  • Windows 安装 Docker 和 Docker Compose
  • arcgis中用python脚本批量给多个要素类的相同字段赋值
  • 目标客户营销(ABM)结合开源AI智能名片2+1链动模式S2B2C商城小程序的策略与实践
  • 《异步编程之美》— 全栈修仙《Java 8 CompletableFuture 对比 ES6 Promise 以及Spring @Async》
  • 新模型设计:Hybrid Quantum-Classical Neural Network (HQCNN) for Image Classification
  • iOS 中spring动画的使用
  • 初学stm32 --- DMA直接存储器
  • 校医院挂号及预约 APP 的设计与实现
  • 代理模式详解与应用
  • Model-based RL自动出价算法的演进之路
  • .NET AI 开发人员库 --AI Dev Gallery简单示例--问答机器人
  • 框架部分面试题学习
  • tdengine数据库使用java连接
  • Java 模板变量替换——字符串替换器(思路Mybatis的GenericTokenParser)
  • 跨界融合:人工智能与区块链如何重新定义数据安全?
  • android 自定义SwitchCompat,Radiobutton,SeekBar样式
  • 计算机网络的定义与发展历程
  • 对比学习 (Contrastive Learning) 算法详解与PyTorch实现
  • DBeaver执行本地的sql语句文件避免直接在客户端运行卡顿
  • C++ 的 pair 和 tuple
  • Zookeeper 集群安装
  • git merge与rebase区别以及实际应用
  • kvm虚拟机出现应用程序无法正常启动报0xc0000142错误
  • Redis 安装与 Spring Boot 集成指南
  • Flink集成TDEngine来批处理或流式读取数据进行流批一体化计算(Flink SQL)拿来即用的案例