Android Jetpack架构组件之 Paging(使用、源码篇)

Android-Jetpack架构组件(一)带你了解Android-Jetpack DataBinding:以声明方式将可观察数据绑定到界面元素,通常和ViewModel配合使用。 Lifecycle:用于管理Activity和Fragment的生命周期,可帮助开发者生成更易于维护的轻量级代码。 LiveData: 在底层数据库更改时通知视图。它是一个可观察的数据持有者,与常规observable不同,LiveData是生命周期感知的。 Navigation:处理应用内导航。 Paging:可以帮助开发者一次加载和显示小块数据,按需加载部分数据可减少网络带宽和系统资源的使用。 Room:友 阅读详情

1、前言

最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面。

Android Architecture组件是Android Jetpack的一部分,它们是一组库,旨在帮助开发者设计健壮、可测试和可维护的应用程序,包含一下组件:

上述时Android Architecture所提供的架构组件,本文主要从使用和源码的角度分析Paging组件

2、Paging简介

  • 分页库概述
  1. Paging Library中DataSource,PagedList,PagedAdapter三者之间的关系以及数据加载到数据展示的流程

比如当一条新的item插入到数据库,DataSource会被初始化,LiveData后台线程就会创建一个新的PagedList。这个新的PagedList会被发送到UI线程的PagedListAdapter中,PagedListAdapter使用DiffUtil在对比现在的Item和新建Item的差异。当对比结束,PagedListAdapter通过调用RecycleView.Adapter.notifyItemInserted()将新的item插入到适当的位置

  • PagedList:是Paging Library的关键组件,它是一个异步加载应用程序数据块或页面的集合
  • Data
  1. 每个PagedList实例都会加载应用程序DataSource的最新数据
  2. 数据从应用程序的后端或数据库流入PagedList对象
  • UI:PagedList类与 PagedListAdapter一起加载 数据到RecyclerView中
  • Paging组件好处
  1. 分页库可以更轻松地在应用程序中的RecyclerView逐步和优雅地加载数据
  2. 数据请求消耗的网络带宽更少,系统资源更少
  3. 即使在数据更新和刷新期间,应用程序仍会继续快速响应用户输入

3、Paging组件的使用

3.1、添加依赖

def paging_version = "1.0.0"
implementation "android.arch.paging:runtime:$paging_version"
testImplementation "android.arch.paging:common:$paging_version"
implementation "android.arch.paging:rxjava2:1.0.0-rc1"

3.2、Paging使用步骤

  • 定义分页配置
  1. Page size :页面大小即每次加载时加载的数量
  2. Prefetch distance:预取距离,给定UI中最后一个可见的Item,超过这个item应该预取一段数据
  3. UI占位符:setEnablePlaceholders()
val myPagingConfig = PagedList.Config.Builder()       // 分页设置
        .setPageSize(50)
        .setPrefetchDistance(150)
        .setEnablePlaceholders(true)
        .build()
  • 使用分页配置创建LiveData<PagedList> ,传入DataSource.Factory,用于创建DataSource,从DataSource中加载数据到PagedList中
val concertList = LivePagedListBuilder(myConcertDataSource, myPagingConfig)
        .setFetchExecutor(myExecutor)
        .build()
  • 观察LiveData<PagedList>,在数据改变时调用适配器刷新数据
viewModel.concertList.observe(this, { pagedList ->
                adapter.submitList(pagedList) })

3.3、Paging和Room的使用

  • 在Room的@Dao中添加查询方法
@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll() : DataSource.Factory<Int,User>  // 返回DataSOurce.Factory配合PagingList使用
}
  • 在ViewModel中查询数据库并创建LiveData<PagedList>
class ViewModelUser(application: Application) : AndroidViewModel(application) {
      val dao = UserDataBase.getInstence(application)?.getDao()
////传入Room返回的DataSource.Factory
      var liveArray : LiveData<PagedList<User>> = 
LivePagedListBuilder(dao!!.getAll(),PagedList.Config.Builder() 
              .setPageSize(10)
              .setPrefetchDistance(10)
              .setEnablePlaceholders(true)
              .build()).build()
}
  • 创建PagedListAdapter的实现类,加载并显示数据
class Adapter : PagedListAdapter<User, Adapter.UserViewHolder>(diffCallback) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
      return UserViewHolder(layoutInflater.inflate(R.layout.item,parent,false))
     }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val user = getItem(position)
        if (user != null){
            holder.bind(user)
        }else{
            holder.clear()
        }
      }

    companion object {
        val diffCallback = object : DiffUtil.ItemCallback<User>() {
            override fun areItemsTheSame(oldItem: User?, newItem: User?): Boolean {
              return  oldItem?.id == newItem?.id
            }
            override fun areContentsTheSame(oldItem: User?, newItem: User?): Boolean {
                return oldItem == newItem
               }
        }
    }
    class UserViewHolder(val view : View) :
            RecyclerView.ViewHolder(view){
        private val  tvId : TextView = view.findViewById(R.id.tvId)
        private val  tvName : TextView = view.findViewById(R.id.tvName)

        fun bind(user: User){
            tvId.text = user.id.toString()
            tvName.text = user.name
        }

        fun clear(){
            tvName.text = null
            tvId.text = null
        }
}

这里说一下传入的DiffUtil.ItemCallback<> 实例,当数据加载到PagedListAdapter时,会回调DiffUtil.ItemCallback中两个抽象方法,确认数据和之前是否发生了改变,如果改变则调用Adapter更新数据:

  1. areItemTheSame():是否为同一个Item
  2. areContentsTheSame():数据内容是否发生变化
  • 添加LiveData<PagedList>观察者

        
Jetpack全系列组件实战短视频App Navigation:强大的APP导航组件,能够为Activity,Fragment,Dialog,FloatWindow提供导航。Paging:强大的分页库组件,能够自动化加载页面初始化和分页(向前分页,向后分页)数据。LiveData:基于生命周期的消息订阅组件,不会发生内存泄漏,不用反注册。Room:灵活易用的数据库组件,对sqlite做了上层包装,无缝对接LiveData。ViewModel:数据共享组件,能够实现数据的存储和页面间数据共享。 阅读详情

相关推荐

Android Jetpack 之 Paging3的一些踩坑记录

前言 使用时多多少少遇到到了一些问题,去翻了源码发现 Paging3 的实现涉及到挺多协程的内容,但是自己对协程也是一知半解,所以文中的看法以及解决方案可能存在错误或不合理的地方。 简单使用 写这篇文章的时候虽然网上的使用教程寥寥无几,但是仅有的几篇讲的都很详细。结合官方的文档 Paging 3 library overview 自己再仔细琢磨一下使用起来基本没什么问题,这里就不再多做赘述。 注:关于paging3版本的问题,目前网上使用教程好像都是3.0.0-alpha02这个版本,这个版本存在一个bug

鸿蒙开发知识记录 2981

jetpack之paging源码解析

参考资料:https://mp.weixin.qq.com/s/aoBAuiuSRvfyCpnHGYrpwA;如果没有现在这么爱较真的心情,直接查看以上地址完全能够理解,而且写得也很好,以下也是参考这篇文章的。(我就是个搬代码的瓦匠工,如有雷同,时间在我前都算我借鉴的,以下字是我一行行敲的) 非常重要的原理图(网上拷贝)以及源码结构(自行剪切) 原理图基本上说明了paging分页的工作原理。源码确实类名比较多,根据原理图以及实际操作来按顺序讲解。 类介绍 这里先不做介绍,按照PagingWithNetwo

foshengtang的博客 591

Android Jetpack深度指南:高效学习与精通之路

学习Jetpack不是一蹴而就的过程,而是持续演进的旅程。建议按照“先用起来,再深究原理前两周:快速实现一个简单应用,感受组件便利性1-2个月:通过完整项目串联多个组件长期:关注官方更新,逐步学习新组件如Compose记住,实践是最好的老师。每学一个组件,立即编码实践;遇到问题,先查官方文档再搜索社区解答。随着Jetpack生态的不断完善,掌握它将使你在Android开发领域保持领先优势。扩展建议:建立个人学习笔记,记录每个组件的使用场景、坑点和最佳实践。

dongdeaiziji的专栏 1350

Android Jetpack 之 Paging3的一些踩坑记录,flutter登录并保持会话

查不到api就去源码里看看。在 Pager 类注释中有提到,每个 PagingData 代表支持分页数据的快照,数据刷新时应该提供一个新的 PagingData 实例,其实在各个教程中并没有提到该如何实现跳页功能,通过这段描述就可以想到跳页功能就需要提供一个新的 PagingData 实例。 那么 PagingData 实例是在什么时候提供的,在类 PageFetcher 中有具体的实现 val flow: Flow<PagingData> = channelFlow { refreshChan

m0_64382868的博客 865

Android Jetpack架构开发组件化应用实战,字节跳动+阿里+华为+腾讯等大厂Android面试题

首页功能首页分为5个Tab,主要为首页、项目、导航、体系和我的。整个页面框架使用BottomNavigationView + Navigation来搭建。通过menu来配置底部菜单。通过NavHostFragment来配置各个fragment。系统提供的FragmentNavigator的navigate方法中是通过replace来加载fragment。这就导致在切换Tab的时候fargment会重复的调用onCreateView方法。这肯定不是我们需要的。

m0_60721649的博客 623

从0搭建Jetpack版的WanAndroid客户端

1、项目目的:  在接触Android Jetpack组件时, 就深深被其巧妙的设计和强大的功能所吸引,暗自告诉自己一定要学会这些组件,而网上并不能找到系统的学习资料,于是利用每天的时间访问Google Developers,把Jetpack的每个组件从使用到源码进行了系统的学习和总结,于是就有了带你领略Android Jetpack组件的魅力系列文章,希望在总结自己学习的同时,也能帮助需要这些...

浅谈Android 8414

Android Jetpack Compose Paging+SwipeRefresh实现分页和下拉刷新

interface RetrofitService { @GET(“getContent”) suspend fun getContentByTitle(@Query(“page”) page: Int, @Query(“title”) title: String): AgResponse<List> } 定义PagingSource class ContentPageSource(val title: String, private val mService: RetrofitService)

m0_64319298的博客 576

Jetpack Paging3 基本使用

Paging3 Paging3,是Jetpack提供给开发者用来显示本地或者网络数据集的分页库。针对这类场景,传统的做法是用RecyclerView的加载更多来实现分页加载,很多逻辑需要自行处理且不一定完善。Paging3相当于是官网提供的一套解决方案。 特点 每一页的数据会缓存至内存中,以此保证处理分页数据时更有效的使用系统资源 内置请求重复数据删除功能,确保应用有效地使用网络带宽和系统资源 支持Kotlin协程、Flow、LiveData以及RxJava 内置错误处理支持,如刷新和重试功能。 逻

AndroidKt 5862

Paging 3 分组列表

前言 为什么命名为 “Android Jetpack” ? Android JetPack = Android Jet Pack = 安卓喷气发动机组件。再看看下面这个直冲云霄的 Android 机器人,是不是觉得还挺有意思? 虽说天天混迹技术社区耳濡目染 Android Jetpack,但是鲜有机会实践。今天就从 Paging3 开始,上手这套组件。 Paging3 是 Google 推出的一个应用于Android平台的分页加载库。相较于历史版本,Paging3 功能更丰富、更易用。 主要优势如下:

AndroidKt 2054

双轮差动机器人SLAM实战:轮速里程计从建模到精度验证(附Matlab代码)

本文详细介绍了双轮差动机器人SLAM系统中轮速里程计的实现全流程,包括核心原理、建模方法、Matlab代码实现及精度验证。通过轮速仪数据建模和连续积分算法,提升定位精度,并附有完整的误差分析和工程优化技巧,为开发者提供实用参考。

weixin_29050271的博客 224

开箱即用的Platform IO开发平台(包括Arduino,ESP8266,ESP32,STM32)

开箱即用的 Platform IO 离线开发环境,包含(ESP32,ESP32S2,ESP8266,Arduino,STM32)

qq_19703307的博客 755

《uni-app 长列表优化:虚拟列表(vue-virtual-scroller)解决 1000+ 数据渲染卡顿》(附虚拟列表封装与多端适配)

本文详细介绍了虚拟列表技术在前端长列表渲染中的优化方案。针对传统v-for渲染导致的性能问题(内存占用高、渲染阻塞、滚动卡顿),提出基于vue-virtual-scroller的虚拟列表解决方案,通过可视区域渲染和DOM复用实现性能突破。文章包含核心原理、组件封装、多端适配及性能对比,并给出常见问题的解决方法。实践表明,该方案可将1000条数据的首次渲染时间从3800ms降至420ms,滚动FPS提升至55帧,显著改善用户体验。

qq_59041750的博客 2108

用Unity Wheel Collider做坦克转向?3步实现履带式载具物理效果

本文详细解析了如何利用Unity的Wheel Collider组件实现履带式载具的差速转向物理效果。通过思维转换、场景搭建和核心代码实现三步,将Wheel Collider从模拟轮式车辆转向改造为控制履带扭矩差的系统,并深入探讨了参数调试与真实感提升的方法,帮助开发者打造物理反馈扎实的坦克或特种车辆模拟。

weixin_29009971的博客 223

2026华为OD机考新系统真题 + 双机位C卷 + 往年真题 - 题库目录分值说明 + 考点说明+在线OJ

2026年4月1日起,华为OD机试正式切换至新系统模式!采用力扣模式,无需自己写输入! 难度大幅度降低。正在备考华为OD机试的同学,优先刷新系统机试真题,可大幅提升通过率。 新系统考题考点与旧版一致,无需重新适应。本专栏所有算法题均配有详细思路解析,并提供C语言、JS、C++、Python、Go、Java多语言源码实现。订阅后私信即可开通专属OJ刷题权限,高效备考一次上岸!

算法大师! 45万+

安全监控:人员行为分析_(2).人员行为分析基础理论

人员行为分析是指利用计算机视觉技术对视频中的人类行为进行实时或离线检测、识别和理解的过程。视频采集:通过摄像头等设备获取视频数据。视频预处理:对视频数据进行噪声过滤、图像增强等处理,以便后续分析。特征提取:从视频中提取出与人员行为相关的特征,如人体姿势、动作轨迹等。行为识别:利用机器学习或深度学习模型对提取的特征进行分类,识别出具体的人员行为。行为理解:对识别出的行为进行进一步分析,理解其背后的意图或状态。在人员行为分析中,常用的公开数据集包括UCF101、HMDB51、ActivityNet等。

zhubeibei168的博客 1345

基于Simulink的占空比调制DTC降低转矩脉动

修改传统SVPWM模块,输入占空比d和有效矢量索引,计算Ton​=d∗Tc​、Toff​=(1−d)∗Tc​,生成对称PWM波形(替代开关表直接输出)。:低速时(n<500rpm)减小dmax​=0.6(避免磁链畸变),高速时(n>2000rpm)增大dmax​=0.8(提升动态响应);kT​/kψ​:转矩/磁链误差增益(需整定,如kT​=0.02/(N⋅m),kψ​=0.1/Wb);(θ为电压矢量与磁链夹角)。② SVM-DTC(占空比计算模块启用,d0​=0.5,kT​=0.02,kψ​=0.1)。

amy_mhd的博客 87

【VTKExamples::PolyData】第十六期 GradientFilter

本文分享VTK样例GradientFilter,并解析接口vtkGradientFilter & vtkAssignAttribute,希望对各位小伙伴有所帮助!

qq_40041064的博客 320

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

上一篇: Android Jetpack架构组件之WorkManger
下一篇: 带你领略Android Jetpack组件的魅力
Alex@W
博客等级 码龄10年 234粉丝 89原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值