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.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;&…