前言

在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.pswp.cn/diannao/95363.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/95363.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/95363.shtml

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

相关文章

扎实基础!深入理解Spring框架,解锁Java开发新境界

大家好&#xff0c;今天想和大家聊聊Java开发路上绕不开的一个重要基石——Spring框架。很多朋友在接触SpringBoot、SpringCloud这些现代化开发工具时&#xff0c;常常会感到吃力。究其原因&#xff0c;往往是对其底层的Spring核心机制理解不够透彻。Spring是构建这些高效框架的…

Heterophily-aware Representation Learning on Heterogeneous Graphs

Heterophily-Aware Representation Learning on Heterogeneous Graphs (TPAMI 2025) 计算机科学 1区 I:18.6 top期刊 📌 摘要 现实世界中的图结构通常非常复杂,不仅具有全局结构上的异质性,还表现出局部邻域内的强异质相似性(heterophily)。虽然越来越多的研究揭示了图…

计算机视觉(7)-纯视觉方案实现端到端轨迹规划(思路梳理)

基于纯视觉方案实现端到端轨迹规划&#xff0c;需融合开源模型、自有数据及系统工程优化。以下提供一套从模型选型到部署落地的完整方案&#xff0c;结合前沿开源技术与工业实践&#xff1a; 一、开源模型选型与组合策略 1. 感知-预测一体化模型 ViP3D&#xff08;清华&#…

Nginx 屏蔽服务器名称与版本信息(源码级修改)

Nginx 屏蔽服务器名称与版本信息&#xff08;源码级修改&#xff09; 一、背景与目的 在生产环境部署 Nginx 时&#xff0c;默认配置会在 Server 响应头中暴露服务类型&#xff08;如 nginx&#xff09;和版本号&#xff08;如 nginx/1.25.4&#xff09;。这些信息可能被攻击者…

从钢板内部应力视角,重新认识护栏板矫平机

一、为什么钢板会“自带波浪”&#xff1f; 钢卷在热轧后冷却、卷取、长途运输、多次吊运时&#xff0c;不同部位受到的温度、张力、碰撞并不一致&#xff0c;内部会产生不均匀的残余应力。应力大的区域想“伸长”&#xff0c;应力小的区域想“缩短”&#xff0c;宏观上就表现为…

C++中的`auto`与`std::any`:功能、区别与选择建议

引言 在C编程中&#xff0c;auto和std::any是两个功能强大但用途不同的工具。理解它们的区别和适用场景对于编写高效、可维护的代码至关重要。本文将详细介绍auto和std::any的基本概念、使用方法、适用场景以及它们之间的区别&#xff0c;并提供选择建议&#xff0c;帮助开发者…

【Linux】进程(Process)

一、什么是进程二、进程的创建三、进程的状态四、僵尸进程五、孤儿进程六、进程的优先级 以及 并发/并行七、进程的切换一、什么是进程&#xff1f;什么是进程呢(一)?官方话来说&#xff1a;进程是一个执行实例、正在执行的程序、是系统资源分配的基本单位按课本官方话可能有一…

销售管理系统哪个好?14款软件深度对比

本文将深入对比14款销售管理系统&#xff1a;1.纷享销客&#xff1b; 2.Zoho CRM&#xff1b; 3.神州云动 CRM&#xff1b; 4.励销云 CRM&#xff1b; 5.Microsoft Dynamics 365 CRM&#xff1b; 6.悟空 CRM&#xff1b; 7.泛微 CRM&#xff1b; 8.HubSpot CRM&#xff1b; 9.…

如何从 0 到 1 开发企业级 AI 应用:步骤、框架与技巧

本文来自作者 莫尔索 的 企业级 AI 应用开发与最佳实践指南&#xff0c; 欢迎阅读原文。 大家好&#xff0c;我之前出版的《LangChain 编程&#xff1a;从入门到实践》一书获得了良好的市场反响和读者认可。近期推出了第二版&#xff0c;我对内容进行了大幅更新&#xff1a;近 …

【LLM】Openai之gpt-oss模型和GPT5模型

note gpt-oss模型代理能力&#xff1a;使用模型的原生功能进行函数调用、网页浏览&#xff08;https://github.com/openai/gpt-oss/tree/main?tabreadme-ov-file#browser&#xff09;、Python 代码执行&#xff08;https://github.com/openai/gpt-oss/tree/main?tabreadme-o…

Ubuntu 20.04 虚拟机安装完整教程:从 VMware 到 VMware Tools

目录 一、VMware的安装 1. 资源获取 1. 网盘提取 2. VMware官网&#xff0c;选择自己合适的版本&#xff0c;我下载的是16.2版本 2.安装步骤 二、Ubuntu的安装 1. Ubuntu 镜像文件官网下载 2. Ubuntu的安装步骤 第一步&#xff1a;打开刚刚安装好的VMware16.2.0&#…

【DL】最优化理论和深度学习

最优化理论是计算机科学中一个重要的概念&#xff0c;它用于帮助我们找到最优解&#xff08;即最小或最大值&#xff09;的算法。在深度学习中&#xff0c;最优化理论用于帮助深度学习模型找到最优解。训练误差&#xff08;Training Error&#xff09;&#xff1a;指模型在训练…

商品分类拖拽排序设计

商品分类、菜单项以及其他需要排序的元素常常会用到拖拽排序功能。这个看似简单的交互背后&#xff0c;其实涉及到一系列复杂的后端逻辑处理&#xff0c;尤其是在如何高效地更新数据库记录方面。本文将探讨两种常见的实现方案&#xff0c;并分析各自的优缺点&#xff0c;帮助你…

ROS机器人云实践设计申报书-草稿

ROS机器人云实践作品申报书 ROS机器人云实践设计一、项目基本信息 项目名称&#xff1a;基于ROS的移动机器人云实践平台设计与应用 申报单位&#xff1a;[具体单位名称] 项目负责人&#xff1a;[具体参与人员] 申报日期&#xff1a;[填写日期] 二、项目背景与目标 项目背景&…

Jira 根据问题类型 为 描述 字段添加默认值

背景: jira 8.16 想要为问题类型为 需求 的问题默认增加描述字段默认值 想都没想直接根据之前添加缺陷类型时描述默认值的方式去添加(系统字段--描述--上下文和默认值--添加上下文), 结果不随我愿, 系统默认的这个功能不能根据问题类型切换而切换不同的默认值, 只能设置 1 个…

深度学习(5):激活函数

ss激活函数的作用是在隐藏层引入非线性&#xff0c;使得神经网络能够学习和表示复杂的函数关系&#xff0c;使网络具备非线性能力&#xff0c;增强其表达能力。一、常见激活函数1、sigmoid激活函数的作用是在隐藏层引入非线性&#xff0c;使得神经网络能够学习和表示复杂的函数…

洛谷 小 Y 拼木棒 贪心

题目背景上道题中&#xff0c;小 Y 斩了一地的木棒&#xff0c;现在她想要将木棒拼起来。题目描述有 n 根木棒&#xff0c;现在从中选 4 根&#xff0c;想要组成一个正三角形&#xff0c;问有几种选法&#xff1f;答案对 1097 取模。输入格式第一行一个整数 n。第二行往下 n 行…

飞算JavaAI的“盾牌”计划:手撕Spring Security + JWT认证链

一、飞算JavaAI&#xff1a;智能时代Java开发的“全能引擎” 1.1 飞算JavaAI&#xff1a;重新定义Java安全开发的“技术革命”在数字化浪潮席卷全球的今天&#xff0c;Java作为企业级应用开发的首选语言&#xff0c;其安全性需求随着业务复杂度的提升而呈指数级增长——从用户认…

大语言模型提示工程与应用:大语言模型进阶提示工程技术

高级提示词使用 学习目标 掌握大语言模型中进阶提示工程技术的原理与应用&#xff0c;包括零样本/少样本提示、思维链推理、知识生成等核心方法&#xff0c;提升复杂任务解决能力。 相关知识点 零样本与少样本提示思维链提示技术高级推理技术 学习内容 1 零样本与少样本提…

【从零开始java学习|第五篇】项目、模块、包、类的概念与联系

目录 一、概念与作用&#xff1a;从宏观到微观的层级拆分 1. 项目&#xff08;Project&#xff09;&#xff1a;最外层的 "大容器" 2. 模块&#xff08;Module&#xff09;&#xff1a;项目的 "功能子单元" 3. 包&#xff08;Package&#xff09;&…