Kotlin Jetpack Paging3 和Flow结合使用注意点

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

在用DataBinding时要注意DataBinding访问的是静态方法

在kotlin中就要用companion object和@JvmStatic

class ImageViewBindingAdapter {//里面的BindingAdapter方法必须是静态方法,否则会编译会报错//DataBinding调用必须是静态方法companion object {@JvmStatic@BindingAdapter("image")fun setImage(imageView:ImageView, url: String){if (!TextUtils.isEmpty(url)){//加载网络图片}else{imageView.setBackgroundColor(Color.GRAY)}}}
}

paging3分页数据错乱的问题

在计算paging的prevKey和nextKey,也就是上一页,下一页的时候,需要考虑PagingConfig中的initialLoadSize参数

fun loadMovie(): Flow<PagingData<Movie>> {return Pager(config = PagingConfig(pageSize = 8,//第一次加载的数量,16也就是2页,默认是3*pageSizeinitialLoadSize = 16),pagingSourceFactory = {MoviePagingSource()}).flow
}class MoviePagingSource: PagingSource<Int, Movie>() {override fun getRefreshKey(state: PagingState<Int, Movie>): Int? {//第一次加载return 1}override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Movie> {val currentPage = params.key ?: 1val pageSize = params.loadSizeval movies = RetrofitClient.createApi(MoviesApi::class.java).getMovies(currentPage, pageSize)var prevKey: Int? = nullvar nextKey: Int? = null//PagingConfig中的2个参数val realPageSize = 8val initialLoadSize = 16if (currentPage == 1){prevKey = nullnextKey = initialLoadSize / realPageSize + 1}else{prevKey = currentPage - 1nextKey = if (movies.hasMore) currentPage + 1 else null}//下面这样计算,在initialLoadSize不等于realPageSize的时候会有数据错乱//prevKey = if (currentPage == 1) null else currentPage - 1//nextKey = if (movies.hasMore) currentPage + 1 else nullreturn try {LoadResult.Page(data = movies.movieList,prevKey = prevKey,nextKey = nextKey)}catch (e: Exception){e.printStackTrace()return LoadResult.Error(e)}}}

给paging加上拉加载更多

recycleView.adapter = movieAdapter.withLoadStateFooter(MovieLoadMoreAdapter(this@MainActivity))

只需要加个适配器就可以

class MovieLoadMoreAdapter(private val context: Context): LoadStateAdapter<BindViewHolder>() {override fun onBindViewHolder(holder: BindViewHolder, loadState: LoadState) {}override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): BindViewHolder {val binding = MovieLoadmoreBinding.inflate(LayoutInflater.from(context), null, false)return BindViewHolder(binding)}
}

paging加上下拉刷新

  • 布局加上SwipeRefreshLayout
<androidx.swiperefreshlayout.widget.SwipeRefreshLayoutandroid\:id="@+id/swipeRefreshLayout"android\:layout\_width="match\_parent"android\:layout\_height="match\_parent"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycleView"android:layout_width="match_parent"android:layout_height="match_parent"app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /></androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
  • 加上刷新监听
swipeRefreshLayout.setOnRefreshListener {movieAdapter.refresh()
}
  • 监听刷新结束
lifecycleScope.launchWhenCreated {movieAdapter.loadStateFlow.collectLatest { state ->mBinding.swipeRefreshLayout.isRefreshing = state.refresh is LoadState.Loading}
}

下拉刷新后,底部上拉加载更多的loadmore的动画不显示

  • PageConfig还有一个属性是prefetchDistance,预刷新的距离,距离最后一个item多远时加载数据,默认为pageSize
  • 当prefetchDistance很小,并且initialLoadSize也很小时,就会出现上面的bug。比如initialLoadSize=8,prefetchDistance=1时
  • 解决办法也比较简单,2个属性设置的大一点就行了

APP横竖屏切换之后paging加载的数据没有缓存起来

  • ViewModel缓存数据要在属性中
  • 还有就是paging返回的是flow,需要用**cachedIn(viewModelScope)**来让paging的flow的生命周期和ViewModelScope的生命周期保持一致,也就是和activity保持一致
class MovieViewModel: ViewModel() {private val movies by lazy {Pager(config = PagingConfig(pageSize = 8,//第一次加载的数量,16也就是2页initialLoadSize = 16,//预刷新的距离,距离最后一个item多远时加载数据,默认为pageSizeprefetchDistance = 8),pagingSourceFactory = {MoviePagingSource()}).flow.cachedIn(viewModelScope)}fun loadMovie(): Flow<PagingData<Movie>> = movies}

欢迎关注我的公众号查看更多精彩文章!

AntDream

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

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

相关文章

MySQl基础入门⑬.5

创建多表连接查询 表准备 CREATE TABLE 员工信息 (员工号 INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,姓名 VARCHAR(50) NOT NULL,性别 ENUM(男, 女) NOT NULL,出生日期 DATE NOT NULL,部门 VARCHAR(50) NOT NULL,手机号码 VARCHAR(20) NOT NULL,-- 根据数据库不同&#x…

NVIDIA NIM推理微服务集成6款新模型

NIM(NVIDIA Inference Microservice)最新模型实例 得益于不断涌现的突破性基础模型&#xff0c;生成式 AI 正在彻底改变各行各业的几乎所有用例。这些模型能够理解背景和原因&#xff0c;从而生成高质量的内容和高精度答案。 NVIDIA 不断优化和发布新的模型。本文将为您介绍最…

ctfshow-web入门-爆破(web25)及php_mt_seed工具的安装与使用

爆个&#x1f528;&#xff0c;不爆了 hexdec() 函数用于将十六进制字符串转换为十进制数&#xff1b; 注意&#xff1a; 我最开始做这道题时看错了&#xff0c;误以为随机数的种子直接来自于 flag 的前八位&#xff0c;以为就是 ctfshow{ 这八个字符然后 md5 加密再截取&a…

【DSP】【第六篇】开发支持包

1. SYS/BIOS发展历史 2. 下载链接 全目录链接。 2.1 SYS/BIOS DSP/BIOS和SYS/BIOS链接 2.1.1 DSP/BIOS 2.1.2 SYS/BIOS SYS/BIOS下载链接下图红框标记的是CCSv5可以使用的最新的版本。 2.1.2.1 网络驱动与协议栈 SYS/BIOS组件之网络驱动与协议栈 &#xff08;1&#xf…

2024年Google算法更新打击低质量(如AI生成)内容后,英文SEO优化人员该如何调整谷歌SEO优化策略?

3月5日&#xff0c;谷歌发布了2024年的首次算法更新。与以往更新不同&#xff0c;本次更新更加复杂&#xff0c;这次更新旨在提高搜索结果的质量和相关性&#xff0c;可能对外贸网站排名和流量产生显著影响。也将产生更大的网站数据波动。但在担心自己的网站数据受到影响之前&a…

MYSQL三、MYSQL的函数与约束

一、函数 函数&#xff1a;是指一段可以直接被另一段程序调用的程序或代码。MySQL中的函数主要分为以下四类&#xff1a; 字符串函数、数值函数、日期函数、流程函数。 1、字符串函数 -- concat : 字符串拼接 select concat(Hello , MySQL); -- 输出&#xff1a; Hello M…

通用代码生成器应用场景六,为完善的应用系统收集需求

通用代码生成器应用场景六&#xff0c;为完善的应用系统收集需求 使用急就章功能可以开发一个简单的应用先凑和着使用。此应用系统也可以成为完善的应用系统的原型和祖先。如果您新规划一个完善的应用系统&#xff0c;您可以先使用通用代码生成器生成一个临时使用的系统&#x…

人脸识别系统之动态人脸识别

二&#xff0e;动态人脸识别 1.摄像头人脸识别 1.1.导入资源包 import dlib import cv2 import face_recognition from PIL import Image, ImageTk import tkinter as tk import os注&#xff1a;这些导入语句允许您在代码中使用这些库和模块提供的功能&#xff0c;例如创建…

Cacti EZ中文版 12.2.27 ISO 下载安装

简介 修改了yum源为中国高校联合镜像源 github改为gitee。 系统增加中文语言包。 修改时区为东八区。 增加了常用的软件包。 PS&#xff1a;CactiEZ是一个自动化安装cacti和插件的ISO镜像&#xff0c;本教程的ISO是基于官方的IOS针对国内网络做了修改。 可按照目前最新的Ca…

Java1.8 vue版家政服务系统成品源码 家政管家系统源码 家政月嫂系统源码 家政保洁系统源码 在线派单,师傅入驻全套商业源码

Java1.8 vue版家政服务系统成品源码 家政管家系统源码 家政月嫂系统源码 家政保洁系统源码 在线派单&#xff0c;师傅入驻全套商业源码 一、系统定义 家政上门服务系统是一种利用互联网技术&#xff0c;将家政服务需求与专业的家政服务人员进行高效匹配的平台。它允许用户通过…

【OceanBase诊断调优】—— obdiag 工具助力OceanBase数据库诊断调优(DBA 从入门到实践第八期)

1. 前言 昨天给大家分享了【DBA从入门到实践】第八期&#xff1a;OceanBase数据库诊断调优、认证体系和用户实践 中obdiag的部分&#xff0c;今天将其中的内容以博客的形式给大家展开一下&#xff0c;方便大家阅读。 2. 正文 在介绍敏捷诊断工具之前&#xff0c;先说说OceanBa…

springboot配置

springboot配置 配置文件分类 springboot提供了多种属性配置方式 application.xml(只有老的spring项目使用)application.propertiesapplication.yml(或yaml) 优先级:properties>yml>yaml 配置文件 pom.xml★ 在Spring Boot项目中&#xff0c;pom.xml文件是Maven项目…

PLM系统与PDM系统、ERP系统、CRM系统有哪些关系?

在当今快速发展的信息技术时代&#xff0c;企业信息化已成为提升管理水平和增强竞争力的关键。其中&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;作为企业信息化的基石&#xff0c;与其他信息系统如产品数据管理&#xff08;PDM&#xff09;、企业资源规划&#xf…

基于SpringBoot+Vue的公园管理系统的详细设计和实现(源码+lw+部署文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还…

如何自建yum源仓库

文章目录 1&#xff0c;创建可用的yum源文件夹&#xff0c;把你自己的软件包&#xff0c;并放在这个目录文件夹中2&#xff0c;将yum源文件夹目录复制到/var/www/html/中3&#xff0c;客户端修改配置文件4&#xff0c;创建一个 RPM 软件包存储库5&#xff0c;查验是否成功6&…

Dify快速接入微信

一、Dify简介 项目官网&#xff1a;Dify.AI 生成式 AI 应用创新引擎 Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务&#xff08;Backend as Service&#xff09;和 LLMOps 的理念&#xff0c;使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非…

ESP32-C3模组上跑通OTA升级(11)

接前一篇文章&#xff1a;ESP32-C3模组上跑通OTA升级&#xff08;10&#xff09; 本文内容参考&#xff1a; 《ESP3-C3 物联网工程开发实战》 乐鑫科技 特此致谢&#xff01; 上一回说到解决了证书验证的问题&#xff0c;但紧接着又出现了一个新的问题&#xff1a;版本相同无…

QT等比例缩放图片

1、这里使用QLabe控件显示图片&#xff0c;如下&#xff1a; label->setPixmap(QPixmap::fromImage(image_2)); 以上是直接原始大小来显示QImage image_2图片。 label->setAlignment(Qt::AlignCenter); 以上代码&#xff0c;是将显示的图片居中展示&#xff0c;默认…

Vue3-Pinia(大菠萝)附源码

文章目录 Pinia 开源地址Pinia 定义与起源优点与特性Pinia使用准备一个小模块(可参考以下程序)搭建 pinia 环境存储读取数据修改数据(三种方式)storeToRefsgetters$subscribestore组合式写法 更多相关内容可查看 Pinia 开源地址 git地址&#xff1a;https://gitee.com/its-a-l…

干货分享 | 详解TSMaster CAN 与 CANFD 的 CRCE2E 校验方法

面对切换工具链的用户来说&#xff0c;在 TSMaster 上完成总线通讯中的 CRC/E2E 校验处理不是特别熟悉&#xff0c;该文章可以协助客户快速使用 TSMaster 完成 CAN/CAN FD 总线通讯的 CRC/E2E 校验。 本文关键字&#xff1a;TSMaster&#xff0c;CAN/CANFD&#xff0c;CRC 校验…