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

JetPack系列教程(六):Paging——让分页加载不再“秃”然

前言

在Android开发的世界里,分页加载就像是一场永无止境的马拉松,每次滚动到底部,都仿佛在提醒你:“嘿,朋友,还有更多数据等着你呢!”但别担心,Google大佬们早就看透了我们的烦恼,于是推出了Jetpack Paging组件,让分页加载变得轻松又优雅。今天,我们就来聊聊这个神奇的组件,看看它是如何让我们的开发生活变得更加美好的。[2][8]

Paging是什么?能吃吗?

首先,Paging是一个分页库,它可以帮助我们优雅地渐进加载大型数据集合,同时减少网络带宽和系统资源的消耗。简单来说,就是让你的应用在加载大量数据时,依然能够保持流畅,就像吃了德芙巧克力一样丝滑。[10]

Paging的四大金刚

Paging之所以强大,离不开它的四大核心类:

  1. RecyclerView:负责列表展示,就像餐厅的菜单,把各种美食(数据)展示给顾客(用户)。[2][8]
  2. PagedListAdapter:RecyclerView的适配器,同时负责通知PagedList何时加载更多数据。它就像餐厅的服务员,知道什么时候该上菜(加载数据)。[2][8]
  3. PagedList:控制分页加载的逻辑,比如加载的数量、每页的大小等。它就像餐厅的厨师长,掌控着整个厨房的节奏。[2][8]
  4. DataSource:执行数据获取的逻辑,它本身并不存储数据,获取到数据后丢给PagedList存储。它就像餐厅的采购员,负责把新鲜的食材(数据)带回来。[2][8]

Paging的三大分页术

Paging支持三种分页方式,就像武侠小说里的三大绝学,各有千秋:

  1. PositionalDataSource:支持从任意位置开始,取多少条数据的方式。这就像你在餐厅点菜,说“从第10道菜开始,给我上20道”。[2][8]
  2. PageKeyedDataSource:以页信息加载数据的场景,比如“pageIndex=1&pageSize=20”。这就像你在餐厅说“给我来第一页菜单,每页20道菜”。[2][8]
  3. ItemKeyedDataSource:根据上一条数据的信息加载下一条数据,比如社交评论中的“maxId=nextId&count=200”。这就像你在餐厅说“给我上完这道菜后,再根据这道菜的风格,给我推荐下一道”。[2][8]

实战:用Paging加载GitHub仓库

说了这么多,是时候来点实战了。假设我们要展示GitHub上所有Android相关的开源库,以Star数量排序,每页返回5条数据。[12]

1. 引入依赖

首先,我们需要在build.gradle文件中添加Paging的依赖:

def paging_version = "3.0.0"
implementation "androidx.paging:paging-runtime-ktx:$paging_version"

2. 创建数据模型类

data class Repo(val id: Int,val name: String,val description: String,val starCount: String
)

3. 定义网络请求接口

interface ApiService {@GET("search/repositories?sort=stars&q=Android")suspend fun searRepos(@Query("page") page: Int, @Query("per_page") perPage: Int): RepoResponsecompanion object {private const val BASE_URL = "https://api.github.com/"fun create(): ApiService {return Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build().create(ApiService::class.java)}}
}

4. 配置数据源

自定义一个子类继承PagingSource,重写load()函数:

class RepoPagingSource(private val apiService: ApiService) : PagingSource<Int, Repo>() {override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Repo> {return try {val page = params.key ?: 1val pageSize = params.loadSizeval repoResponse = apiService.searRepos(page, pageSize)val repoItems = repoResponse.itemsval prevKey = if (page > 1) page - 1 else nullval nextKey = if (repoItems.isNotEmpty()) page + 1 else nullLoadResult.Page(repoItems, prevKey, nextKey)} catch (e: Exception) {LoadResult.Error(e)}}
}

5. 在ViewModel中实现接口请求

class RepoViewModel : ViewModel() {private val apiService = ApiService.create()fun getPagingData(): Flow<PagingData<Repo>> {return Pager(PagingConfig(pageSize = 5, prefetchDistance = 5)) {RepoPagingSource(apiService)}.flow.cachedIn(viewModelScope)}
}

6. UI层展示数据

在Activity或Fragment中,给RecyclerView设置Adapter,并监听数据变化:

class MainActivity : AppCompatActivity() {private val viewModel by lazy { ViewModelProvider(this).get(RepoViewModel::class.java) }private val adapter: RepoAdapter by lazy { RepoAdapter() }override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val recyclerView: RecyclerView = findViewById(R.id.recyclerView)recyclerView.layoutManager = LinearLayoutManager(this)recyclerView.adapter = adapterlifecycleScope.launchWhenCreated {viewModel.getPagingData().collectLatest { pagingData ->adapter.submitData(pagingData)}}}
}

结语

通过上面的实战,我们可以看到,Paging组件让分页加载变得如此简单。它不仅减少了我们的代码量,还提高了应用的性能和用户体验。[10]所以,下次当你再遇到分页加载的需求时,不妨试试Paging组件,让你的开发生活变得更加轻松愉快![10]

好了,今天的教程就到这里。如果你觉得有用,别忘了点赞、分享和关注哦!我们下期再见!

http://www.xdnf.cn/news/17818.html

相关文章:

  • 职场与生活如何在手机中共存?(二)
  • aliases 的意义和作用?
  • Harmony OS 开发入门 第三章
  • 四、深入剖析Java程序逻辑控制:从字节码到性能优化
  • Android 双屏异显技术全解析:从原理到实战的多屏交互方案
  • sqli-libs通关教程(51-65)
  • Linux系统编程Day13 -- 程序地址空间(进阶)
  • 18.9 BERT问答模型实战:从数据到部署的完整指南
  • dolphinscheduler 依赖节点不通过
  • 【Spring Boot 3.0 + JDK 17 新手指南:完整用户管理系统】
  • ADB 无线调试连接(Windows + WSL 环境)
  • AI一周事件(2025年8月6日-8月12日)
  • 字符串匹配算法
  • 深度学习——03 神经网络(3)-网络优化方法
  • cisco无线WLC flexconnect配置
  • latex中“itemize”
  • 了解 Linux 中的 /usr 目录以及 bin、sbin 和 lib 的演变
  • 肖臻《区块链技术与应用》第十一讲:比特币核心概念重温:一文读懂私钥、交易、挖矿与网络现状
  • 深入解析 AUTOSAR:汽车软件开发的革命性架构
  • Qt中定时器介绍和使用
  • 什么是跨域访问问题,如何解决?
  • 企业高性能web服务器(3)
  • cartographer 后端优化流程
  • 终端安全检测与防御技术
  • MySQL 存储过程终止执行的方法
  • [TryHackMe]Internal(hydra爆破+WordPress主题修改getshell+Chisel内网穿透)
  • MyBatis 缓存与 Spring 事务相关笔记
  • 安路Anlogic FPGA下载器的驱动安装与测试教程
  • 扩展 Chat2File-deepseek V4.0 正式发布:不仅是更新,更是一次“重塑”
  • 实验-vlan实验