Paging3的使用踩坑记录

一、Paging3介绍

Paging3是jetpack推出的一个分页加载库,用于方便开发者实现分页加载功能,支持显示加载状态,重试机制,支持协程与RxJava结合使用,相对于传统的分页加载方案,我们不需要关注recyclerview的滑动状态,然后根据状态去实时请求接口,所有相关的判断逻辑,Paging3已经在内部为我们做好了实现,我们只需要实现Paging3的提供的抽象方法,即可实现分页加载功能

二、Paging3的依赖添加

// Paging3默认使用协程,如果不需要使用RxJava,则只引入这一个依赖即可
implementation 'androidx.paging:paging-runtime:3.1.1'// 如果需要使用RxJava,则需要在引入这个依赖
implementation "androidx.paging:paging-rxjava2:3.1.1"

三、Paging3的使用

Paging3的使用需要关注三个类:

1、PagingDataAdapter

使用方法与RecyclerView的adapter几乎一致,需要注意的是,PagingDataAdapter默认添加了DiffUtil,需要我们手动实现DiffUtil的对比方法

2、Pager

Paging3提供的封装工具,提供配置分页参数,数据请求形式,页面加载逻辑等配置操作

3、SourceFactory

我们需要实现此类,用于实现数据的请求与加载逻辑

/*** 时间:2022/5/29 00:33 * 作者:菜籽* 备注:Paging3的数据适配器,需要实现DiffUtil方法*/class AdapterPaging3 : PagingDataAdapter<ItemPaging3, AdapterPaging3.ViewHolder>(itemComparator) {companion object {val itemComparator = object : DiffUtil.ItemCallback<ItemPaging3>() {/*** 用来判断新旧条目是否一样,确定是否需要刷新* 只有当此方法返回true时,才会执行下面的方法* 如果此方法返回false,则下面的方法不会执行* 举个例子:当前item的布局没有发生变化,只是布局里面的数据发生了变化,*          比如字符串从AAA变成了BBB,则这里返回true,表示不需要重绘当前item的布局**/override fun areItemsTheSame(oldItem: ItemPaging3, newItem: ItemPaging3): Boolean {return true}/*** 用来确定是否是同一条目是否一样* 注意与上面的方法区分* 这里返回true时,只会刷新当前item布局中发生变化的那一部分UI,其余地方不需要动* 如果这里返回false,则当前item不会刷新,显示内容也不会发生变化*/override fun areContentsTheSame(oldItem: ItemPaging3, newItem: ItemPaging3): Boolean {return !TextUtils.equals(oldItem.title, newItem.title)}}}class ViewHolder(view: View) : RecyclerView.ViewHolder(view)override fun onBindViewHolder(holder: ViewHolder, position: Int) {holder.itemView.tv_title.text = getItem(position)?.title}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_item_paging3, parent, false)return ViewHolder(view)}}
val pagingConfig = PagingConfig(/*** 每页显示的数据数量,* 注意这个页,并不等同于我们接口中定义的条数* 这个数量的意思是,每一个页面会加载这么多数据* 举个例子,如果接口每页返回10条,而这里定义了20条,则Paging3会请求两次接口,* 用来拼成这20条数据*/pageSize = 60,// 开启占位符,在加载到正确数据之前,显示的item布局enablePlaceholders = true,// 预刷新的距离,距离最后一个 item 多远时加载数据prefetchDistance = 3,/*** 初始化加载数量,默认为 pageSize * 3** internal const val DEFAULT_INITIAL_PAGE_MULTIPLIER = 3* val initialLoadSize: Int = pageSize * DEFAULT_INITIAL_PAGE_MULTIPLIER*/initialLoadSize = 60,/*** 一次应在内存中保存的最大数据* 超出这个数字的数据会被销毁,当页面滑回来时,会重新请求此页面的数据,* 滑动加载更多的数据*/maxSize = 200
)
/*** 时间:2022/5/29 00:35* 作者:菜籽* 备注:使用viewModel+协程的形式来请求数据*/class Paging3Coroutines {private val repository by lazy {val config = PagingConfig(pageSize = 20, initialLoadSize = 5, maxSize = 150)val sourceFactory = object : PagingSource<Int, ItemPaging3>() {/*** 官方解释:每当paging想要加载新的数据来代替当前列表时,会发生刷新操作,回调到这个方法** 使用场景:* 比如说你当前是第三页,然后用户此时回到第二页时,数据发生变化了,不再前面加载好的数据了,* 此时就可以在这里返回第二页的索引,它会重新请求第二页的内容用来展示** 目前还没有遇到过这种需求*/override fun getRefreshKey(state: PagingState<Int, ItemPaging3>): Int? {return null}/*** 我这里定义的为每页显示10条数据* 模拟网络加载失败的情况*/override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ItemPaging3> {val currentPage = params.key ?: 0Log.d("ItemDataSource", "currentPage:$currentPage")if (currentPage > 0) {val random = Math.random()delay((random * 3000).toLong())}val list = mutableListOf<ItemPaging3>()for (i in 0..9) {list.add(ItemPaging3("第" + (10 * currentPage + i) + "条"))}val prevKey = if (currentPage == 0) null else currentPage - 1val nextKey = currentPage + 1if (!NetStateHelper.isConnect) {return LoadResult.Error(ConnectException())}if (currentPage == 4) {// nextKey为null表示数据加载到头了return LoadResult.Page(list, prevKey, null)}return LoadResult.Page(list, prevKey, nextKey)}}Pager(config, pagingSourceFactory = { sourceFactory })}fun getData() = repository.flow.asLiveData()}

四、高级用法:

1、显示加载状态:

Paging3支持设置header和footer用来显示当前的加载状态,我们需要声明一个adapter实现LoadStateAdapter来显示加载状态,具体代码如下:

/*** 时间:2022/5/28 23:32* 作者:菜籽* 备注:网络状态的适配器*/class LoadStateAdapterPaging3 : LoadStateAdapter<LoadStateAdapterPaging3.LoadStateViewHolder>() {class LoadStateViewHolder(view: View) : RecyclerView.ViewHolder(view)private var listener: (() -> Unit)? = nullfun setOnReloadClickListener(listener: () -> Unit) {this.listener = listener}/*** loadState 有三种状态**/override fun onBindViewHolder(holder: LoadStateViewHolder, loadState: LoadState) {Log.d("ItemDataSource", "loadState:$loadState")holder.itemView.progress_bar.visibility = View.VISIBLEholder.itemView.tv_state.text = "正在加载中..."if (loadState is LoadState.NotLoading) {if (loadState.endOfPaginationReached) {holder.itemView.progress_bar.visibility = View.GONEholder.itemView.tv_state.text = "数据加载完毕"} else {holder.itemView.tv_state.text = "滑到头了,继续加载"}return}if (loadState is LoadState.Error) {holder.itemView.tv_state.text = "加载失败,点击重试"holder.itemView.progress_bar.visibility = View.GONEholder.itemView.setOnClickListener {listener?.invoke()}return}}override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): LoadStateViewHolder {val view = LayoutInflater.from(parent.context).inflate(R.layout.load_state_item_paging3, parent, false)return LoadStateViewHolder(view)}/*** 是否显示当前的加载状态* 默认的是只有 loading中,loading失败时才会显示加载状态* 我们可以改掉super的代码,添加一条当加载完成时,也显示加载状态*/override fun displayLoadStateAsItem(loadState: LoadState): Boolean {//return super.displayLoadStateAsItem(loadState)return loadState is LoadState.Loading || loadState is LoadState.Error || (loadState is LoadState.NotLoading && loadState.endOfPaginationReached)}}

2、与数据展示相结合:

//通过融合两个adapter实现数据适配器与页面加载适配器融合
adapter.withLoadStateFooter(loadAdapter)

3、与RxJava相结合

/*** 时间:2022/5/29 00:39 * 作者:菜籽* 备注:Paging3与RxJava结合使用*/class Paging3RxJava {private val repository by lazy {val config = PagingConfig(pageSize = 20, initialLoadSize = 5, maxSize = 150)val sourceFactory = object : RxPagingSource<Int, ItemPaging3>() {override fun getRefreshKey(state: PagingState<Int, ItemPaging3>): Int? {return null}override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, ItemPaging3>> {val currentPage = params.key ?: 0val delay = if (currentPage > 0) {val random = Math.random()random * 3000} else {0f}.toLong()return Single.just("").delay(delay, TimeUnit.MILLISECONDS).map {val list = mutableListOf<ItemPaging3>()for (i in 0..9) {list.add(ItemPaging3("第" + (10 * currentPage + i) + "条"))}val prevKey = if (currentPage == 0) null else currentPage - 1val nextKey = currentPage + 1if (!NetStateHelper.isConnect) {return@map LoadResult.Error(ConnectException())}if (currentPage == 4) {// nextKey为null表示数据加载到头了return@map LoadResult.Page(list, prevKey, null)}return@map LoadResult.Page(list, prevKey, nextKey)}}}Pager(config, pagingSourceFactory = { sourceFactory })}fun getData() = repository.flow.asLiveData()}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/150697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

铝合金钻孔铣削去毛刺加工之高速电主轴解决方案

铝合金是一种轻质、高强度的材料&#xff0c;其出色的机械性能和良好的导电性、导热性使其在工业领域广受青睐特别是在航空、航天和汽车制造中&#xff0c;铝合金的身影更是随处可见。在铝合金加工过程中&#xff0c;高速电主轴可精准而高效地完成钻孔、铣削和去毛刺等任务&…

Python大数据之linux学习总结——day09_hive调优

hive调优 hive官方配置url: https://cwiki.apache.org/confluence/display/Hive/ConfigurationProperties hive命令和参数配置 hive参数配置的意义: 开发Hive应用/调优时&#xff0c;不可避免地需要设定Hive的参数。设定Hive的参数可以调优HQL代码的执行效率&#xff0c;或帮…

云原生周刊:Istio 1.20.0 发布 | 2023.11.20

开源项目推荐 DevPod DevPod 是一款纯客户端工具&#xff0c;可在任何后端基于 devcontainer.json 创建可重现的开发人员环境。每个开发者环境都在一个容器中运行&#xff0c;并通过 devcontainer.json 进行指定。通过 DevPod 提供商&#xff0c;这些环境可以在任何后端创建&…

SpringBoot3 Actuator使用如何以及自定义端点

参考: https://www.yuque.com/leifengyang/springboot3/wsx0br0dalot1pqn 作用: 对线上应用进行观测、监控、预警… 比如: ● 健康状况【组件状态、存活状态】Health ● 运行指标【cpu、内存、垃圾回收、吞吐量、响应成功率…】Metrics ● 链路追踪 1.使用 1.场景引入 <…

拼多多官方开放平台接口app商品详情接口获取实时商品详情数据演示

拼多多开放平台提供了一种名为“商品详情接口”的API接口&#xff0c;它允许卖家从自己的系统中快速获取商品信息&#xff0c;如商品标题、描述、价格、库存等&#xff0c;并将这些信息展示在自己的店铺中。通过该接口&#xff0c;卖家可以更好地管理自己的商品库存和销售&…

投资黄金:如何选择正确的黄金品种增加收益?

黄金一直以来都是备受投资者青睐的避险资产&#xff0c;然而&#xff0c;在庞大的黄金市场中&#xff0c;选择适合自己的黄金品种成为影响收益的关键因素。黄金投资并不只有一种方式&#xff0c;而是有很多种不同的黄金品种可以选择。每种黄金品种都有其独特的特点和风险&#…

python连接hive报错:TypeError: can‘t concat str to bytes

目录 一、完整报错 二、解决 三、 其他报错 一、完整报错 Traceback (most recent call last): File "D:/Gitlab/my_world/hive2csv.py", line 18, in <module> conn hive.Connection(hosthost, portport, usernameusername, passwordpassword, data…

【HarmonyOS开发】设备调试避坑指南

备注&#xff1a;通过开发验证&#xff0c;发现每个设备调试都会存在不小的差别&#xff0c;开发验证需要注意~ 1、预览器调试&#xff08;只能预览具有Entry修饰的文件&#xff09; 修改文件&#xff0c;预览器将自动刷新 注意&#xff1a;当我们只修改了Component 组件的文件…

【Linux】套接字编程

目录 套接字 IP PORT TCP和UDP的介绍 TCP UDP 网络字节序 转换接口 UDP服务器的编写 服务器的初始化 socket bind sockaddr 结构 服务器的运行 数据的收发 业务处理 客户端的编写 运行效果 拓展 套接字 &#x1f338;首先&#xff0c;我们先思考一个问题…

【深度学习】pytorch快速得到mobilenet_v2 pth 和onnx

在linux执行这个程序&#xff1a; import torch import torch.onnx from torchvision import transforms, models from PIL import Image import os# Load MobileNetV2 model model models.mobilenet_v2(pretrainedTrue) model.eval()# Download an example image from the P…

韦东山linux驱动开发学习【常更】

1.linux目录简单介绍 2.直接运行需要在$path路径下

windows 安裝字體Font

或者直接Copy到C:\Windows\fonts 目錄下

maven 添加 checkstyle 插件约束代码规范

本例示例&#xff0c;是引用 http 链接这种在线 checkstyle.xml 文件的配置方式&#xff0c;如下示例&#xff1a; <properties><maven.checkstyle.plugin.version>3.3.0</maven.checkstyle.plugin.version><!--支持本地绝对路径、本地相对路径、HTTP远程…

用三智者交易策略澳福加减仓轻松盈利,就是这么厉害

就是这么厉害&#xff0c; 用三智者交易策略&#xff0c;澳福通过加减仓就可以在交易市场中轻松盈利。各位投资者都知道三智者交易策略的两个重要的原则。当市场超过外部极限时&#xff0c;在向上分形的高点和向下分形的低点&#xff0c;就会跟随外部方向/分形点。 fpmarkets澳…

如何使用Docker部署Apache+Superset数据平台并远程访问?

大数据可视化BI分析工具Apache Superset实现公网远程访问 文章目录 大数据可视化BI分析工具Apache Superset实现公网远程访问前言1. 使用Docker部署Apache Superset1.1 第一步安装docker 、docker compose1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网…

LLM大模型 (chatgpt) 在搜索和推荐上的应用

目录 1 大模型在搜索的应用1.1 召回1.1.1 倒排索引1.1.2 倒排索引存在的问题1.1.3 大模型在搜索召回的应用 (实体倒排索引&#xff09; 1.2 排序1.2.1 大模型在搜索排序应用&#xff08;融入LLM实体排序&#xff09; 2 大模型在推荐的应用2.1 学术界关于大模型在推荐的研究2.2 …

什么是硬分叉?硬分叉的原因是什么?硬分叉的影响是什么?

目录 什么是硬分叉? 硬分叉的原因是什么? 区块大小的改变 共识机制的修改

在vscode中使用Latex:TexLive2023

安装TexLive2023及配置vscode可参考https://zhuanlan.zhihu.com/p/166523064 然后编译模板 .tex文件时&#xff0c;出现以下几个错误&#xff1a; 1. ctexbook找不到字体集 d:/texlive/2023/texmf-dist/tex/latex/ctex/ctexbook.cls:1678: Class ctexbook Error: CTeX fo…

采用Nexus搭建Maven私服

采用Nexus搭建Maven私服 1.采用docker安装 1.创建数据目录挂载的目录&#xff1a; /usr/local/springcloud_1113/nexus3/nexus-data2.查询并拉取镜像docker search nexus3docker pull sonatype/nexus33.查看拉取的镜像docker images4.创建docker容器&#xff1a;可能出现启动…

OpenWrt环境下,由于wget不支持ssl/tls导致执行opkg update失败的解决方法

执行&#xff1a; opkg update 显示&#xff1a; wget: SSL support not available, please install one of the libustream-ssl-* libraries as well as the ca-bundle and ca-certificates packages. 提示opkg依赖的wget不支持ssl/tls。 此时需要下载支持ssl/tls的wget。但是…