6. Jetpack---Paging你知道怎样上拉加载吗?

之前的几篇源码分析我们分别对NavigationLifecyclesViewModelLiveData、进行了分析,也对JetPack有了更深入的了解。但是Jetpack远不止这些组件,今天的主角—Paging,Jetpack中的分页组件,官方是这么形容它的:‘’逐步从您的数据源按需加载信息‘’

如果你对Jetpack组件有了解或者想对源码有更深入的了解,请看我之前的几篇文章:

1. Jetpack源码解析—看完你就知道Navigation是什么了?

2. Jetpack源码解析—Navigation为什么切换Fragment会重绘?

3. Jetpack源码解析—用Lifecycles管理生命周期

4. Jetpack源码解析—LiveData的使用及工作原理

5. Jetpack源码解析—ViewModel基本使用及源码解析

1. 背景

在我的Jetpack_Note系列中,对每一篇的分析都有相对应的代码片段及使用,我把它做成了一个APP,目前功能还不完善,代码我也上传到了GitHub上,参考了官方的Demo以及目前网上的一些文章,有兴趣的小伙伴可以看一下,别忘了给个Star。

https://github.com/Hankkin/JetPack_Note

今天我们的主角是Paging,介绍之前我们先看一下效果:

19-08-10-11-18-59.2019-08-10 11_33_51

2. 简介

2.1 基本介绍

官方定义:

分页库Pagin LibraryJetpack的一部分,它可以妥善的逐步加载数据,帮助您一次加载和显示一部分数据,这样的按需加载可以减少网络贷款和系统资源的使用。分页库支持加载有限以及无限的list,比如一个持续更新的信息源,分页库可以与RecycleView无缝集合,它还可以与LiveData或RxJava集成,观察界面中的数据变化。

2.2 核心组件

1. PagedList

PageList是一个集合类,它以分块的形式异步加载数据,每一块我们称之为。它继承自AbstractList,支持所有List的操作,它的内部有五个主要变量:

  1. mMainThreadExecutor 主线程Executor,用于将结果传递到主线程
  2. mBackgroundThreadExecutor 后台线程,执行负载业务逻辑
  3. BoundaryCallback 当界面显示缓存中靠近结尾的数据的时候,它将加载更多的数据
  4. Config PageList从DataSource中加载数据的配置
  5. PagedStorage 用于存储加载到的数据

Config属性:

  1. pageSize:分页加载的数量
  2. prefetchDistance:预加载的数量
  3. initialLoadSizeHint:初始化数据时加载的数量,默认为pageSize*3
  4. enablePlaceholders:当item为null是否使用placeholder显示

PageList会通过DataSource加载数据,通过Config的配置,可以设置一次加载的数量以及预加载的数量。除此之外,PageList还可以想RecycleView.Adapter发送更新的信号,驱动UI的刷新。

2. DataSource

DataSource<Key,Value> 顾名思义就是数据源,它是一个抽象类,其中Key对应加载数据的条件信息,Value对应加载数据的实体类。Paging库中提供了三个子类来让我们在不同场景的情况下使用:

  1. PageKeyedDataSource:如果后端API返回数据是分页之后的,可以使用它;例如:官方Demo中GitHub API中的SearchRespositories就可以返回分页数据,我们在GitHub API的请求中制定查询关键字和想要的哪一页,同时也可以指明每个页面的项数。
  2. ItemKeyedDataSource:如果通过键值请求后端数据;例如我们需要获取在某个特定日期起Github的前100项代码提交记录,该日期将成为DataSource的键,ItemKeyedDataSource允许自定义如何加载初始页;该场景多用于评论信息等类似请求
  3. PositionalDataSource:适用于目标数据总数固定,通过特定的位置加载数据,这里Key是Integer类型的位置信息,T即Value。 比如从数据库中的1200条开始加在20条数据。

3. PagedListAdapter

PageListAdapter继承自RecycleView.Adapter,和RecycleView实现方式一样,当数据加载完毕时,通知RecycleView数据加载完毕,RecycleView填充数据;当数据发生变化时,PageListAdapter会接受到通知,交给委托类AsyncPagedListDiffer来处理,AsyncPagedListDiffer是对**DiffUtil.ItemCallback**持有对象的委托类,AsyncPagedListDiffer使用后台线程来计算PagedList的改变,item是否改变,由DiffUtil.ItemCallback决定。

3.基本使用

3.1 添加依赖包

implementation "androidx.paging:paging-runtime:$paging_version" // For Kotlin use paging-runtime-ktx
    implementation "androidx.paging:paging-runtime-ktx:$paging_version" // For Kotlin use paging-runtime-ktx
    // alternatively - without Android dependencies for testing
    testImplementation "androidx.paging:paging-common:$paging_version" // For Kotlin use paging-common-ktx
    // optional - RxJava support
    implementation "androidx.paging:paging-rxjava2:$paging_version" // For Kotlin use paging-rxjava2-ktx

3.2 PagingWithRoom使用

新建UserDao

/**
 * created by Hankkin
 * on 2019-07-19
 */
@Dao
interface UserDao {
   


    @Query("SELECT * FROM User ORDER BY name COLLATE NOCASE ASC")
    fun queryUsersByName(): DataSource.Factory<Int, User>

    @Insert
    fun insert(users: List<User>)

    @Insert
    fun insert(user: User)

    @Delete
    fun delete(user: User)

}

创建UserDB数据库

/**
 * created by Hankkin
 * on 2019-07-19
 */
@Database(entities = arrayOf(User::class), version = 1)
abstract class UserDB : RoomDatabase() {
   

    abstract fun userDao(): UserDao
    companion object {
   
        private var instance: UserDB? = null
        @Synchronized
        fun get(context: Context): UserDB {
   
            if (instance == null) {
   
                instance = Room.databaseBuilder(context.applicationContext,
                    UserDB::class.java, "UserDatabase")
                    .addCallback(object : RoomDatabase.Callback() {
   
                        override fun onCreate(db: SupportSQLiteDatabase) {
   
                            fillInDb(context.applicationContext)
                        }
                    }).build()
            }
            return instance!!
        }

        /**
         * fill database with list of cheeses
         */
        private fun fillInDb(context: Context) {
   
            // inserts in Room are executed on the current thread, so we insert in the background
            ioThread {
   
                get(context).userDao().insert(
                    CHEESE_DATA.map {
    User(id = 0, name = it) })
            }
        }
    }
}

创建PageListAdapter

/**
 * created by Hankkin
 * on 2019-07-19
 */
class PagingDemoAdapter : PagedListAdapter<User, P
z-paging插件可以实现底部加载更多的功能。通过使用该插件,您可以在uniapp中实现多条数据滚动显示或者自定义下拉刷新,分页显示等功能。插件提供了一个Footer布局文件,您可以在其中添加加载更多的视图元素,例如加载中的动画和文本提示。当用户滑动到底部时,插件会自动触发加载更多的操作。如果加载失败,用户可以点击重试按钮重新加载请求失败的页的数据。您可以在uniapp的官方插件市场搜索z-paging插件,并参考其接口文档学习如何使用该插件。\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [JetPack知识点实战系列六:Paging实现加载更多和下拉刷新,错误后重新请求](https://blog.csdn.net/lcl130/article/details/108597975)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [uniapp开发使用插件z-paging实现页面下拉刷新、上拉加载,分页加载](https://blog.csdn.net/qq_43799179/article/details/126709149)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值