Android Paging3 基本使用

本文介绍了Android Paging3的基本使用,包括添加依赖、配置数据源(如Room与自定义数据源)、构建分页数据、创建RecyclerView.Adapter、展示分页列表、监听数据加载状态以及设置Header和Footer。Paging3简化了分页加载的复杂性,提供了Room集成和自定义PagingSource的示例。
摘要由CSDN通过智能技术生成

一、前言

Paging3,是Jetpack提供给开发者用来显示本地或者网络数据集的分页库。针对这类场景,传统的做法是用RecyclerView的加载更多来实现分页加载,很多逻辑需要自行处理且不一定完善。Paging3相当于是官网提供的一套解决方案。

下图为您应用的各个层级中推荐直接接入 Paging 的 Android 应用架构
在这里插入图片描述

二、添加依赖

根据语言二选一即可,我使用的是kotlin

//java
implementation 'androidx.paging:paging-runtime:3.0.0-alpha09'
//kotlin
implementation 'androidx.paging:paging-runtime-ktx:3.0.0-alpha09'

三、基本使用

基本使用主要包含如下内容:

  • 配置数据源:PagingSource
  • 构建分页数据:Pager、PagingData
  • 构建RecyclerView Adapter:PagingDataAdapter
  • 展示分页UI列表数据
  • 设置Header和Footer
  • 监听数据加载的状态

3.1 配置数据源

abstract class PagingSource<Key : Any, Value : Any> 

参数解析:

  • Key:分页标识类型,如页码,则为Int
  • Value:返回列表元素的类型

3.1.1 Room

如果使用的是Room,从 2.3.0-alpha 开始,它将默认为您实现 PagingSource。在定义 Dao 接口的 Query 语句时,返回类型要使用 PagingSource 类型。同时不需要在 Query 里指定页数和每页展示数量,页数由 PagingSource 来控制,每页数量页在 PagingConfig 中定义。

@Dao
interface UserDao {
   
    @Query("SELECT * FROM User ORDER BY name COLLATE NOCASE ASC")
    fun allUserByName(): PagingSource<Int, User>

    @Insert
    fun insert(user: User)

    @Delete
    fun delete(user: User)
}

使用 Room 有一个好处是,如果通过 insert() 或 delete() 等方法修改了 Room 里的数据,不需要额外处理就会即时反应在 PagingSource 里,界面上展示的数据会相应变化。

3.1.2 自定义数据源

使用PagingSource
如果不是直接使用 Room 的数据,而是使用源自其他地方的数据,比如网络数据,就需要自定义 PagingSource 了,创建方式如下:

class UserDataSource : PagingSource<Int, User>() {
   
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, User> {
   
        return try {
   
            val page = params.key ?: 0
            //获取网络数据
            val result = Retrofitance.instance.ApiService.getUsers(page)
            LoadResult.Page(
                //需要加载的数据
                data = result.data,
                //如果可以往上加载更多就设置该参数,否则不设置
                prevKey = null,
                //加载下一页的key 如果传null就说明到底了
                nextKey = if (result.curPage == result.pageCount) null else page + 1
            )
        } catch (e: IOException) {
   
            // IOException for network failures.
            return LoadResult.Error(e)
        } catch (e: HttpException) {
   
            // HttpException for any non-2xx HTTP status codes.
            return LoadResult.Error(e)
        }
    }
}

参数解释:

  • data :返回的数据列表
  • prevKey :上一页的key (传 null 表示没有上一页)
  • nextKey :下一页的key (传 null 表示没有下一页)
  • paging3 使用 flow 传递数据,不了解的可以搜索一下flow ;
  • cachedIn:绑定协程生命周期,必须加上,否则可能崩溃;
  • asLiveData:熟悉livedata的都知道怎么用;

使用RemoteMediator

RemoteMediator 和 PagingSource 相似,都需要覆盖 load() 方法,但是不同的是 RemoteMediator 不是加载分页数据到 RecyclerView 列表上,而是获取网络分页数据并更新到数据库中。

区别:

  • PagingSource:实现单一数据源以及如何从该数据源中查找数据,例如 Room,数据源的变动会直接映射到 UI 上
  • RemoteMediator:实现加载网络分页数据并更新到数据库中,但是数据源的变动不能直接映射到 UI 上

在项目中如何进行选择?

  • PagingSource:用于加载有限的数据集(本地数据库)例如手机通讯录等等。
  • RemoteMediator:主要用来加载网络分页数据并更新到数据库中,当我们没有更多的数据时,我们向网络请求更多的数据,结合 PagingSource 当保存更多数据时会直接映射到 UI 上

注意:
RemoteMediator 目前是实验性的 API ,所有实现 RemoteMediator 的类都需要添加 @OptIn(ExperimentalPagingApi::class) 注解。

当我们使用 OptIn 注解,需要在 App 模块下的 build.gradle 文件内添加以下代码

android {
   
    kotlinOptions {
   
        freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn"]
    }
}

@OptIn(ExperimentalPagingApi::class)
class UserRemoteMediator(
    val api: ApiService,
    val db: AppDataBase
) : RemoteMediator<Int, User>() {
   

    override suspend fun load(
        loadType: LoadType,
        state: PagingState<Int, User>
    ): MediatorResult {
   
        try {
   

            /**
             * 在这个方法内将会做三件事
             *
             * 1. 参数 LoadType 有个三个值,关于这三个值如何进行判断
             *      LoadType.REFRESH
             *      LoadType.PREPEND
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值