Paging
下表列出了 androidx.paging
组中的所有工件。
制品 | 稳定版 | 候选版 | Beta 版 | Alpha 版 |
---|---|---|---|---|
paging-* | 3.3.4 | - | - | - |
paging-compose | 3.3.4 | - | - | - |
声明依赖项
如需添加 Paging 的依赖项,您必须将 Google Maven 代码库添加到项目中。如需了解详情,请参阅 Google 的 Maven 代码库。
在应用或模块的 build.gradle
文件中添加所需工件的依赖项:
Groovy
dependencies { def paging_version = "3.3.2" implementation "androidx.paging:paging-runtime:$paging_version" // alternatively - without Android dependencies for tests testImplementation "androidx.paging:paging-common:$paging_version" // optional - RxJava2 support implementation "androidx.paging:paging-rxjava2:$paging_version" // optional - RxJava3 support implementation "androidx.paging:paging-rxjava3:$paging_version" // optional - Guava ListenableFuture support implementation "androidx.paging:paging-guava:$paging_version" // optional - Jetpack Compose integration implementation "androidx.paging:paging-compose:3.3.2" }
Kotlin
dependencies { val paging_version = "3.3.2" implementation("androidx.paging:paging-runtime:$paging_version") // alternatively - without Android dependencies for tests testImplementation("androidx.paging:paging-common:$paging_version") // optional - RxJava2 support implementation("androidx.paging:paging-rxjava2:$paging_version") // optional - RxJava3 support implementation("androidx.paging:paging-rxjava3:$paging_version") // optional - Guava ListenableFuture support implementation("androidx.paging:paging-guava:$paging_version") // optional - Jetpack Compose integration implementation("androidx.paging:paging-compose:3.3.2") }
如需了解如何使用 Kotlin 扩展,请参阅 ktx 文档。
如需详细了解依赖项,请参阅添加构建依赖项。
反馈
您的反馈将帮助我们改进 Jetpack。如果您发现了新问题,或对此库有任何改进建议,请告诉我们。创建新问题前,请先查看此库中的现有问题。您可以点击星标按钮,为现有问题投票。
如需了解详情,请参阅问题跟踪器文档。
3.3 版
版本 3.3.4
2024 年 11 月 13 日
发布了 androidx.paging:paging-*:3.3.4
。版本 3.3.4 包含这些提交内容。
bug 修复
- 拉入 Paging 3.3 或更高版本的 Android 单元测试将不再抛出
Method isLoggable in android.util.Log not mocked
等错误。(Ia9400、b/331684448)
版本 3.3.2
2024 年 8 月 7 日
发布了 androidx.paging:paging-*:3.3.2
。版本 3.3.2 包含这些提交内容。
新功能
paging-common
和paging-testing
添加了新的 Kotlin-Multiplatform 目标:watchos
、tvos
和linuxArm64
(90c9768) (53e0eca)
版本 3.3.1
2024 年 7 月 24 日
发布了 androidx.paging:paging-*:3.3.1
。版本 3.3.1 包含这些提交内容。
bug 修复
- 修复了以下问题:当后备数据源在滚动时刷新时,
AsyncPagingDataDiffer
或基于其构建的 API(例如与RecyclerView
搭配使用的PagingDataAdapter
)无法触发更多加载。(I60ca5、b/352586078) - 修复了在使用
PagingDataAdapter
或AsyncPagingDataDiffer
滚动RecyclerView
时从后备数据源中移除项时发生的崩溃问题。(I8c65a、b/347649763)
版本 3.3.0
2024 年 5 月 14 日
发布了 androidx.paging:paging-*:3.3.0
。版本 3.3.0 包含这些提交内容。
自 3.2.0 以来的重要变更
PagingDataPresenter
现在是一个公共类。现在,您可以基于PagingDataPresenter
构建多平台 Presenter,而无需使用内部分页 API 或paging-runtime
的AsyncPagingDataDiffer
。- 在
hasError
和isIdle
中添加了新的LoadStates
和CombinedLoadStates
辅助方法,分别用于检查LoadStates
是否处于“错误”或NotLoading
状态。此外,还在Flow<CombinedLoadStates>
上添加了新的awaitNotLoading()
Kotlin 扩展方法,该方法会等待加载进入NotLoading
或“错误”状态。 - 现在,除非将自定义
LoadStates
传递给其构造函数,否则PagingData.empty()
会默认调度NotLoading
状态。这与现有行为不同,现有行为是:在提交给PagingDataAdapter
时不会调度LoadStates
,或者在作为LazyPagingItems
收集时调度“正在加载”状态。现在,如果作为LazyPagingItems
收集,它还会在初始组合后立即显示一个空列表。
Kotlin Multiplatform 兼容性
分页功能现在提供与 Kotlin Multiplatform 兼容的工件,这在很大程度上得益于 CashApp 的 multiplatform-paging 项目中上游的工作。
paging-common
已将所有 Paging 3 API 移至common
,现在除了 Android 之外,还与 jvm 和 iOS 兼容。paging-testing
已将其代码移至common
,现在除了 Android 之外,还与 jvm 和 iOS 兼容。paging-compose
已将其代码移至common
并提供了 Android 工件,与androidx.compose
的多平台支持相匹配。paging-runtime
、paging-guava
、paging-rxjava2
和paging-rxjava3
将继续仅限 Android 设备。
版本 3.3.0-rc01
2024 年 5 月 1 日
发布了 androidx.paging:paging-*:3.3.0-rc01
,该版本与 Paging 3.3.0-beta01 相比没有变化。版本 3.3.0-rc01 包含这些提交内容。
版本 3.3.0-beta01
2024 年 4 月 3 日
发布了 androidx.paging:paging-*:3.3.0-beta01
,该版本没有明显变化。版本 3.3.0-beta01 包含这些提交内容。
版本 3.3.0-alpha05
2024 年 3 月 20 日
发布了 androidx.paging:paging-*:3.3.0-alpha05
。版本 3.3.0-alpha05 包含这些提交内容。
API 变更
- 分页现在针对常规代码使用 AndroidX 注解
@MainThread
注解。(I78f0d、b/327682438)
版本 3.3.0-alpha04
2024 年 3 月 6 日
发布了 androidx.paging:paging-*:3.3.0-alpha04
。版本 3.3.0-alpha04 包含这些提交内容。
bug 修复
- 修复了与添加 Kotlin 多平台兼容性相关的轻微文档错误。(aosp/2950785)
版本 3.3.0-alpha03
2024 年 2 月 7 日
发布了 androidx.paging:paging-*:3.3.0-alpha03
。版本 3.3.0-alpha03 包含以下提交内容。
新功能
PagingDataPresenter
现在是一个公共类。现在,您可以基于PagingDataPresenter
构建多平台 Presenter,而无需使用内部分页 API 或paging-runtime
的AsyncPagingDataDiffer
。(Id1f74、b/315214786)- 添加了新的
LoadStates
和CombinedLoadStates
辅助方法,用于检查LoadStates
是处于“错误”状态还是“NotLoading
”状态。此外,还添加了一个新的 API,该 API 会在LoadStateFlow
上等待,直到加载进入NotLoading
或“错误”状态。(Id6c67)
行为变更
- 现在,除非将自定义
LoadStates
传递给其构造函数,否则PagingData.empty()
会默认调度NotLoading
状态。这与现有行为不同,现有行为是:在提交给PagingDataAdapter
时不会调度LoadStates
,或者在作为LazyPagingItems
收集时调度“正在加载”状态。现在,如果作为LazyPagingItems
收集,它还会在初始组合后立即显示一个空列表。(I4d11d、b/301833847)
版本 3.3.0-alpha02
2023 年 9 月 20 日
发布了 androidx.paging:paging-*:3.3.0-alpha02
。版本 3.3.0-alpha02 中包含以下提交内容。
Kotlin Multiplatform 兼容性
分页功能现在提供与 Kotlin Multiplatform 兼容的工件,这在很大程度上得益于 CashApp 的 multiplatform-paging 项目中上游的工作。这样,我们就可以避免两个代码库之间出现分歧,并使其保持兼容性。
paging-common
已将所有 Paging 3 API 移至common
,现在除了 Android 之外,还与 jvm 和 iOS 兼容。paging-testing
已将其代码移至common
,现在除了 Android 之外,还与 jvm 和 iOS 兼容。paging-compose
已将其代码移至common
并提供了 Android 工件,与androidx.compose
的多平台支持相匹配。paging-runtime
、paging-guava
、paging-rxjava2
和paging-rxjava3
将继续仅限 Android 设备。
API 变更
- 仅供内部使用的公共 Logger 接口已废弃 (I16e95、b/288623117)
外部贡献
- 感谢 Cash App 的 veyndan 帮助将 Paging 迁移到 Kotlin Multiplatform (#560、#561、#562、#573、#576、#577、#578、#579、#580、#581、#583、#584、#586、#609)
版本 3.3.0-alpha01
2023 年 9 月 20 日
- 这是 androidx.paging 库的第一个多平台版本。此版本仅包含
*-jvm
和*-android
工件。对于 macOS、iOS 和 Linux 变体,请使用3.3.0-alpha02
。
版本 3.2
版本 3.2.1
2023 年 9 月 6 日
发布了 androidx.paging:paging-*:3.2.1
。版本 3.2.1 中包含这些提交内容。
bug 修复
- 修复了以下问题:分页测试工件的
asSnapshot()
API 在传递使用PagingData.from(List)
构建的流程时会挂起,因为asSnapshot()
没有任何有关加载完成时间的信息(与PagingData.from(List, LoadStates)
过载不同)。此解决方法仅适用于可完成的流程(例如flowOf(PagingData.from(...))
)。对于不可完成的流程(例如MutableStateFlow
,请使用提供LoadStates
的PagingData.from
重载)。(I502c3) - Paging Compose 现在在内部使用
AndroidUiDispatcher.Main
,以确保在加载完成时同一帧中可用新数据。(Ia55af)
版本 3.2.0
2023 年 7 月 26 日
发布了 androidx.paging:paging-*:3.2.0
。版本 3.2.0 中包含这些提交内容。
自 3.1.0 以来的重要变更
- Paging Compose 已达到 API 稳定性,并已合并回 Paging 的其余部分,其版本现与所有其他 Paging 工件一致。自 3.1.0 以来的变更包括:
- 支持通过创建
PagingData.from(fakeData)
并将该PagingData
封装在MutableStateFlow
(例如MutableStateFlow(PagingData.from(listOf(1, 2, 3)))
)中来预览虚构数据列表。将此流程作为接收器传递到@Preview
可组合项,以便collectAsLazyPagingItems()
进行预览。 - 支持所有延迟布局(例如
LazyVerticalGrid
和HorizontalPager
),以及 Wear 和 TV 库中的自定义延迟组件。这通过新的较低级别LazyPagingItems
扩展方法itemKey
和itemContentType
实现,可帮助您将key
和contentType
参数实现到LazyColumn
、LazyVerticalGrid
已有的标准items
API,以及HorizontalPager
等 API 中的等效项。 - 仅支持
LazyListScope
的items(lazyPagingItems)
和itemsIndexed(lazyPagingItems)
已废弃。
- 支持通过创建
- 新的
paging-testing
工件,提供了单独围绕对应用每个层进行单元测试及其与 Paging 的集成而设计的 API。例如,它包含以下内容:TestPager
类,可让您独立于 Pager 和真实界面验证自己的自定义PagingSource
实现的行为。asPagingSourceFactory
API,用于将Flow<List<Value>>
或静态List<Value>
转换为可在测试中传递给 Pager 的PagingSourceFactory
Flow<PagingData<Value>>
上的asSnapshot
Kotlin 扩展,该扩展会将Flow<PagingData<Value>>
转换为直接的List<Value>
。借助asSnapshot lambda
,您可以通过scrollTo
或appendScrollWhile
等 API 来模仿应用的界面,以便验证分页数据集中任何位置的数据快照是否正确。
- 添加了默认日志,以便在两种级别(
VERBOSE
和DEBUG
)中显示分页调试信息。日志可通过命令adb shell setprop log.tag.Paging [DEBUG|VERBOSE]
启用。这适用于使用 View 的分页或使用 Compose 的分页。 - 为
PagingDataAdapter
和AsyncPagingDataDiffer
添加了构造函数,它们接受CoroutineContext
,而不是CoroutineDispatcher
。 - 添加了新的
PagingSourceFactory
函数接口,该接口提供的 API Surface 比之前的 () ->PagingSource
lambda 更明确。此工厂可用于实例化 Pager。
版本 3.2.0-rc01
2023 年 6 月 21 日
发布了 androidx.paging:paging-*:3.2.0-rc01
。版本 3.2.0-rc01 中包含这些提交内容。
外部贡献
版本 3.2.0-beta01
2023 年 6 月 7 日
发布了 androidx.paging:paging-*:3.2.0-beta01
。版本 3.2.0-beta01 中包含这些提交内容。
Paging Compose
- Paging Compose 已正式达到 API 稳定性。因此,该版本已从
1.0.0-alpha20
更新为与所有其他分页工件版本一致。
API 变更
- 从 Paging Compose 中移除了已废弃的
items(LazyPagingItems)
和itemsIndexed(LazyPagingItems)
API。如需查看替代 API 示例,请参阅 Paging Compose1.0.0-alpha20
版本说明。(I9626e)
版本 3.2.0-alpha06
2023 年 5 月 24 日
发布了 androidx.paging:paging-*:3.2.0-alpha06
。版本 3.2.0-alpha06 中包含这些提交内容。
新功能
- 添加了新的
PagingSourceFactory
函数接口,该接口提供的 API 接口比现有的() -> PagingSource
lambda 更明确。此工厂可用于实例化Pager
。(I33165、b/280655188) - 添加了
List<Value>.asPagingSourceFactory()
的新paging-testing
API,以获取仅从不可变数据列表加载的PagingSourceFactory
。您仍应使用Flow<List<Value>>
上的现有扩展程序来测试多代静态数据。(Id34d1、b/280655188)
API 变更
- 分页测试中的所有公共 API 现在都带有
@VisibleForTesting
注解,以确保这些 API 仅用于测试。(I7db6e) asSnapshot
API 不再需要传入CoroutineScope
。现在,它默认使用从其父级作用域继承的上下文。(Id0a78、b/282240990)- 重新排列了
TestPager
构造函数参数,以直观地与实际Pager
构造函数参数的顺序相匹配 (I6185a) - 将分页测试对 lambda 类型
() -> PagingSource<Key, Value>
的使用迁移到了类型PagingSourceFactory<Key, Value>
。(I4a950、b/280655188)
行为变更
- 不再需要主调度程序来运行
asSnapshot
分页测试。设置此参数不会再对测试行为造成任何更改。(Ie56ea)
版本 3.2.0-alpha05
2023 年 5 月 3 日
发布了 androidx.paging:paging-*:3.2.0-alpha05
。版本 3.2.0-alpha05 中包含这些提交内容。
API 变更
asSnapshot
的分页测试 API 现在将其loadOperations
参数默认为空 lambda。这样一来,您无需传入任何加载操作即可调用asSnapshot
,从而从初始刷新加载中检索数据。(Ied354、b/277233770)
文档改进
- 更新了
asPagingSourceFactory()
相关文档,明确指出它是Flow
上的扩展方法,用于返回可重复使用的工厂以生成PagingSource
实例。(I5ff4f、I705b5) - 更新了
LoadResult.Page
构造函数的文档,阐明了需要替换itemsBefore
和itemsAfter
才能支持跳转。(Ied354)
外部贡献
- 感谢 Veyndan 帮助我们将分页从 Android/JVM 具体实现中分离出来。(#525、#523、#520、#519、#507、#506、 #505、 #499、 #497、 #496、 #493)
版本 3.2.0-alpha04
2023 年 2 月 8 日
发布了 androidx.paging:paging-*:3.2.0-alpha04
。版本 3.2.0-alpha04 中包含这些提交内容。
分页测试
paging-testing
工件现在包含一个asPagingSourceFactory
方法,用于根据要提供给 Pager 的Flow<List<Value>>
创建pagingSourceFactory
。从 Flow 发出的每一个List<Value>>
都代表一轮分页数据。这有助于进行 Paging 测试,例如,通过虚构 Pager 用于收集数据的数据源来测试PagingData
转换。(I6f230、b/235528239)paging-testing
工件通过新的 API 进行了扩展,这些新 API 适用于验证包含Flow<PagingData<T>>
的数据是否正确。例如,它可以用于断言 ViewModel 层的Flow<PagingData<T>>
输出。这是通过
Flow<PagingData<Value>>
上的asSnapshot
Kotlin 扩展实现的,该扩展会将Flow<PagingData<Value>>
转换为直接的List<Value>
。借助asSnapshot
lambda,您将能够以可重复且一致的方式通过 API(例如scrollTo
或appendScrollWhile
)来模仿应用的界面,以便验证分页数据集中任何位置的数据快照是否正确。// Create your ViewModel instance val viewModel = … // Get the Flow of PagingData from the ViewModel val data< Flow<PagingData<String>> = viewModel.data val snapshot: List<String> = data.asSnapshot { // Each operation inside the lambda waits for the data to settle before continuing scrollTo(index = 50) // While you can’t view the items within the asSnapshot call, // you can continuously scroll in a direction while some condition is true // i.e., in this case until you hit a placeholder item appendScrollWhile { item: String -> item != “Header 1” } } // With the asSnapshot complete, you can now verify that the snapshot // has the expected values
asSnapshot
是预期在runTest
中运行的suspend
方法。如需了解详情,请参阅在 Android 上测试 Kotlin 协程。(I55fd2、I5bd26、I7ce34、I51f4d、I2249f、Id6223、Ic4bab、Ib29b9、Ic1238、I96def、b/235528239)
API 变更
AsyncPagingDataDiffer
和PagingDataAdapter
中对getItem
和peek
的界面调用现已正确标记为仅可在主线程上调用。(I699b6)- 从
TestPager
使用的通用类型中移除了通配符。这样,您就能更轻松地在以 Java 编程语言编写的代码中使用这些方法的执行结果。(I56c42)
版本 3.2.0-alpha03
2022 年 10 月 24 日
发布了 androidx.paging:paging-*:3.2.0-alpha03
。版本 3.2.0-alpha03 中包含这些提交内容。
分页测试
此版本包含一个新工件:paging-testing
。此工件提供了单独围绕对应用每个层进行单元测试及其与 Paging 的集成而设计的 API。
例如,第一个版本包含一个 TestPager
类,该类可让您独立于 Pager
和您模拟端到端 Paging 集成通常所需的真实界面验证自己的自定义 PagingSource
实现的行为。
TestPager
应被视为虚构 - 这是一个测试替身,用于镜像 Pager
的真实实现,同时提供用于测试 PagingSource
的简化 API Surface。此类 API 是 suspend
API,应在 runTest
中运行,如在 Android 上测试 Kotlin 协程指南中所述。
这些正在使用的 API 的示例可以在重构为使用 TestPager
的 room-paging
测试中找到。
API 变更
- 支持通过
LoadResult.Page.iterator()
便捷地对LoadResult.Page.data
执行迭代。这样就间接允许在给定List<LoadResult.Page>
(例如将PagingState
的pages
属性传递给PagingSource.getRefreshKey
方法)时使用 Kotlin 标准库flatten
方法。(Ie0718)
版本 3.2.0-alpha02
2022 年 8 月 10 日
发布了 androidx.paging:paging-*:3.2.0-alpha02
。版本 3.2.0-alpha02 中包含这些提交内容。
新功能
- Paging 现在通过
AsyncPagingDataDiffer
或PagingDataAdapter
类提供日志,以公开从PagingData
收集的调试信息。 - 日志可通过
adb shell
命令adb shell setprop log.tag.Paging [DEBUG|VERBOSE].
启用 (b/235527159)
bug 修复
- 修复了将
paging-common:3.2.0-alpha01
与运行时paging-runtime:3.1.1
或更低版本一起使用时缺少PagingDataDiffer
构造函数的错误。(b/235256201)
版本 3.2.0-alpha01
2022 年 6 月 1 日
发布了 androidx.paging:paging-*:3.2.0-alpha01
。版本 3.2.0-alpha01 中包含这些提交内容。
API 变更
- 为
PagingDataAdapter
和AsyncPagingDataDiffer
添加了构造函数,它们接受CoroutineContext
,而不是CoroutineDispatcher
。(Idc878) - 默认情况下,
PagingData.from()
和PagingData.empty()
不再对 Presenter 端的CombinedLoadStates
有影响。添加了允许将sourceLoadStates
和remoteLoadStates
传入这些构造函数的新重载,以维持将LoadStates
设置为完全终端(即NotLoading(endOfPaginationReached = false)
)的行为,并根据需要添加远程状态。如果未传递LoadStates
,则前一个CombinedLoadStates
在收到静态PagingData
时会在 Presenter 端保持不变。(Ic3ce5、b/205344028)
bug 修复
- 现在,如果
PagingSource.getRefreshKey()
会返回 null,但设置了非 nullinitialKey
,则 PagingSource.getRefreshKey() 的优先级会正确地高于initialKey
。(Ic9542、b/230391606)
外部贡献
- 由于 test-coroutines-lib 迁移,更新了 :compose:ui:ui-test API (updateApi) (I3366d)
版本 3.1
版本 3.1.1
2022 年 3 月 9 日
发布了 androidx.paging:paging-*:3.1.1
。版本 3.1.1 中包含这些提交内容。
bug 修复
- 移除了
.cachedIn()
在各代之间错误插入的LoadState.NotLoading
中间事件。此更改移除了在刷新或失效时在重试失败加载之间生成的冗余LoadState.NotLoading
事件,从而使系统可以更容易对LoadState
更改做出响应。
版本 3.1.0
2021 年 11 月 17 日
发布了 androidx.paging:paging-*:3.1.0
。版本 3.1.0 中包含这些提交内容。
自 3.0.0 以来的重要变更
Flow<PagingData>.observable
和Flow<PagingData>.flowable
API 不再处于实验阶段LoadState
的行为发生了如下变更:- 对于
PagingSource
和RemoteMediator
,endOfPaginationReached
现在调用LoadType.REFRESH
时始终会返回false
- 现在,Paging 中的
LoadStates
会等待PagingSource
和RemoteMediator
发出有效值后,再发出下游消息。对于刷新状态,现在新生成的PagingData
会在启动时始终正确地处于Loading
,而不是在某些情况下错误地重置为NotLoading
。 - presenter API 上的
.loadStateFlow
和.addLoadStateListener
不再多余地发送初始CombinedLoadStates
,其 mediator 状态始终设为null
- 对于
- 现在,您可以在无效/新生成的 PagingData 上执行以往版本中的取消操作。您应该不再需要在
Flow<PagingData>
上使用.collectLatest
,但我们仍然建议您使用。 - 从
PagingSource.load
中添加了PagingSource.LoadResult.Invalid
作为新的返回类型,这会导致 Paging 舍弃向此PagingSource
发出任何待处理或今后的加载请求,并使该请求失效。此返回类型旨在处理可能会从数据库或网络返回的可能无效或过时的数据。 - 添加了
.onPagesPresented
和.addOnPagesUpdatedListener
presenter API。在界面中呈现页面后会立即触发这些 API。在以下情况下,网页可能会进行更新:- 完成了对新一代 PagingData 的初始加载(不管新一代 PagingData 是否包含对所呈现项的任何更改)。也就是说,如果新一代 PagingData 完成了初始加载,但因列表完全相同而未进行任何更新,其仍会触发此回调。
- 插入了某个页面(即使插入的页面不包含任何新项)。
- 丢弃了某个页面(即使丢弃的页面为空)。
版本 3.1.0-rc01
2021 年 11 月 3 日
发布了 androidx.paging:paging-*:3.1.0-rc01
。版本 3.1.0-rc01 中包含这些提交内容。
bug 修复
- 修复了以下情况下 .cachedIn() 中出现的竞态条件和内存泄漏的问题:在没有观察者时或观察者切换到新的 PagingData 期间,Paging 下游发送了多个加载事件。(Ib682e)
版本 3.1.0-beta01
2021 年 10 月 13 日
发布了 androidx.paging:paging-*:3.1.0-beta01
。版本 3.1.0-beta01 中包含这些提交内容。
bug 修复
- 修复了多次快速访问项导致其在 prefetchDistance 中未被考虑,从而导致网页加载暂停的问题。当系统需要同时排列多个项,并以与用户滚动方向相反的顺序优先加载这些项时,此问题尤为明显。现在,系统会缓冲这些项访问,并同步进行优先级排序,以防止其被丢弃。(aosp/1833273)
版本 3.1.0-alpha04
2021 年 9 月 29 日
发布了 androidx.paging:paging-*:3.1.0-alpha04
。版本 3.1.0-alpha04 中包含这些提交内容。
API 变更
Flow<PagingData>.observable
和Flow<PagingData>.flowable
API 不再处于实验阶段。(Ie0bdd)
bug 修复
- 对于 LoadStates,
endOfPaginationReached
现在调用LoadType.REFRESH
时会始终返回false
。以前,endOfPaginationReached 调用 RemoteMediator(而非 PagingSource)REFRESH
时,可能会返回true
。此行为现在已整合为始终返回false
,因为 REFRESH 无法作为终端命令使用,而且现作为 API 协定的一部分记录在 LoadStates 中。在确定是否终止分页时,您应始终以 APPEND 或 PREPEND 指令为依据。(I047b6) 现在,Paging 中的 LoadStates 会等待 PagingSource 和 RemoteMediator 发出有效值后,再在各代之间发出下游消息。这样可以防止新生成的 PagingData 在 CombinedLoadStates.source.refresh(如果它已处于 Loading 状态)中发送 NotLoading;对于刷新状态,现在新生成的 PagingData 会在启动时始终正确地处于“Loading”状态,而不是在某些情况下错误地首先重置为“NotLoading”。
现在,您可以在无效/新生成的 PagingData 上执行以往版本中的取消操作。您应该不再需要在
Flow<PagingData>
上使用 .collectLatest,但我们仍强烈建议您使用。(I0b2b5、b/177351336、b/195028524)presenter API 上的
.loadStateFlow
和.addLoadStateListener
不再多余地发送初始CombinedLoadStates
,其 mediator 状态始终设为null
,source 状态设为NotLoading(endOfPaginationReached = false)
。这意味着:- 如果您使用 RemoteMediator,则系统始终会预设为 mediator 状态。
- 如果不再接收
PagingData
发送的真实CombinedLoadStates
,那么在.loadStateFlow
上注册新的 loadState 监听器或新收集器时,系统不会再立即发出当前值。如果收集器或监听器在提交PagingData
之前启动,就可能发生这种情况。(I1a748)
版本 3.1.0-alpha03
2021 年 7 月 21 日
发布了 androidx.paging:paging-*:3.1.0-alpha03
。版本 3.1.0-alpha03 中包含这些提交内容。
API 变更
将第三个 LoadResult 返回类型 LoadResult.Invalid 添加到 PagingSource 中。当 PagingSource.load 返回 LoadResult.Invalid 时,Paging 将舍弃加载的数据并使 PagingSource 无效。此返回类型旨在处理可能会从数据库或网络返回的可能无效或过时的数据。
例如,如果底层数据库已被写入,但 PagingSource 没有及时失效,并且它的实现依赖于从中加载它的后备数据集的不变性,那么它可能会返回不一致的结果(例如,LIMIT OFFSET 样式数据库实现)。在这种情况下,建议在加载后检查失效情况并返回 LoadResult.Invalid,这会导致 Paging 舍弃向此 PagingSource 发出任何待处理或今后的加载请求,并使该请求失效。
使用 LivePagedList 或 RxPagedList 的 Paging2 API 也支持此返回值类型。配合使用 PagingSource 与 Paging2 的 PagedList API 时,PagedList 会立即分离,从而停止继续尝试在此 PagedList 上加载数据并在 PagingSource 上触发失效。
LoadResult 是一个密封的类,这意味着这项更改与源代码不兼容,因此直接使用 PagingSource.load 结果的用例必须在编译时处理 LoadResult.Invalid。例如,使用 exhaustive-when 语句检查返回值类型的 Kotlin 用户需要添加对无效类型的检查。(Id6bd3、b/191806126、b/192013267)
bug 修复
- 现在,如果通过 PagingSource.registerInvalidatedCallback 或 DataSource.addInvalidatedCallback 添加的失效回调是在已经无效的 PagingSource/DataSource 上注册的,那么它们会自动触发。这解决了在提供初始加载期间已经无效的源时导致 Paging 丢弃无效信号并卡住的竞态条件问题。此外,现在会在触发后正确移除失效回调,因为系统保证它们最多被调用一次。(I27e69)
- 从最近实例化的 PagedList 流提交占位符初始值 (InitialPagedList),例如,LivePagedListBuilder 或 RxPagedListBuilder 将不再清除之前加载的数据。
版本 3.1.0-alpha02
2021 年 7 月 1 日
发布了 androidx.paging:paging-*:3.1.0-alpha02
。版本 3.1.0-alpha02 中包含这些提交内容。
新功能
添加了 onPagesPresented 监听器和 flow presenter API。在界面中更新呈现的页面后会立即触发这些 API。
由于这些更新是与界面同步的,因此您可以调用 .snapshot、.getItemCount 等适配器方法,以在更新得以应用后检查状态。请注意,.snapshot() 会被显式调用,因为每次进行更新时运行该方法都可能占用大量资源。
在以下情况下,网页可能会进行更新:
- 完成了对新一代 PagingData 的初始加载(不管新一代 PagingData 是否包含对所呈现项的任何更改)。也就是说,如果新一代 PagingData 完成了初始加载,但因列表完全相同而未进行任何更新,其仍会触发此回调。
- 插入了某个页面(即使插入的页面不包含任何新项)
- 丢弃了某个页面(即使丢弃的页面为空)(I272c9、b/189999634)
bug 修复
- 通过 LivePagedList 或 RxPagedList 生成的初始值访问 PagedList.dataSource 时,系统不会再错误地抛出 IllegalStateException (I96707)
版本 3.1.0-alpha01
2021 年 6 月 2 日
发布了 androidx.paging:paging-*:3.1.0-alpha01
。版本 3.1.0-alpha01 中包含这些提交内容。
API 变更
paging-rxjava3
提供的类现在位于androidx.paging.rxjava3
软件包下,因此不会与paging-rxjava2
冲突 (Ifa7f6)
bug 修复
- 修复了 Paging 有时会向 RecyclerView 发送空操作差异事件的问题,这个问题可能会导致某些监听器提前触发。(Ic507f、b/182510751)
外部贡献
- 将已弃用的 PagedList compat API 添加到了 rxjava3 工件中(Id1ce2、b/182497591)
Paging Compose 版本 1.0.0
版本 1.0.0-alpha20
2023 年 5 月 24 日
发布了 androidx.paging:paging-compose:1.0.0-alpha20
。版本 1.0.0-alpha20 中包含这些提交内容。
新功能
- Paging Compose 现在支持通过创建
PagingData.from(fakeData)
并将该PagingData
封装在MutableStateFlow
中(例如,MutableStateFlow(PagingData.from(listOf(1, 2, 3)))
)。通过将这些数据用作@Preview
的输入,对collectAsLazyPagingItems()
的调用将提供可预览的LazyPagingItems
。(I8a78d、b/194544557)
bug 修复
- 现在,在状态恢复后,系统会立即提供在
LazyPagingItems
中收集的pager.flow.cachedIn
缓存数据,而无需异步收集。这意味着,在恢复状态后,缓存的数据将在初始组合时立即准备好进行呈现。(I97a60、b/177245496)
版本 1.0.0-alpha19
2023 年 5 月 3 日
发布了 androidx.paging:paging-compose:1.0.0-alpha19
。版本 1.0.0-alpha19 中包含这些提交内容。
支持所有延迟布局
以前,Paging Compose 在 LazyListScope
上提供自定义 items
和 itemsIndexed
扩展,这意味着您无法将 Paging Compose 与其他延迟布局(例如 LazyVerticalGrid
、HorizontalPager
)或 Wear 和 TV 库提供的其他自定义延迟组件搭配使用。解决这一不灵活性是此版本的主要更新。
为了支持更多延迟布局,我们需要在其他层构建 API。Paging Compose 现在在 itemKey
和 itemContentType
中的 LazyPagingItems
上提供略低级别的扩展方法,而不是为每个延迟布局提供自定义 items
API。这些 API 旨在帮助您将 key
和 contentType
参数实现到 LazyColumn
、LazyVerticalGrid
中已存在的标准 items
API,以及 HorizontalPager
等 API 中的等效 API。(Ifa13b、Ib04f0、b/259385813)
这意味着支持 LazyVerticalGrid
的代码如下所示:
// This part is unchanged
val lazyPagingItems = pager.collectAsLazyPagingItems()
LazyVerticalGrid(columns = GridCells.Fixed(2)) {
// Here we use the standard items API
items(
count = lazyPagingItems.itemCount,
// Here we use the new itemKey extension on LazyPagingItems to
// handle placeholders automatically, ensuring you only need to provide
// keys for real items
key = lazyPagingItems.itemKey { it.uniqueId },
// Similarly, itemContentType lets you set a custom content type for each item
contentType = lazyPagingItems.itemContentType { "contentType" }
) { index ->
// As the standard items call provides only the index, we get the item
// directly from our lazyPagingItems
val item = lazyPagingItems[index]
PagingItem(item = item)
}
}
如需查看有关使用这些新 API 的更多示例,请参阅我们的示例。
虽然这些更改确实会使 LazyColumn
和 LazyRow
示例多出几行代码,但我们认为,对于今后使用 Paging Compose 的用户来说,所有延迟布局的一致性是一项重要因素。因此,LazyListScope
的现有扩展现已废弃。(I0c459、I92c8f、b/276989796)
API 变更
- 为了简化向新 API 的迁移,
LazyListScope
上的items
和itemsIndexed
扩展函数现在支持contentType
参数,与新 API 中的支持保持一致。(Ib1918、b/255283378)
依赖项更新
- Paging Compose 已将其依赖项从 Compose 1.0.5 更新为 Compose 1.2.1。(Ib1918、b/255283378)
版本 1.0.0-alpha18
2023 年 2 月 8 日
发布了 androidx.paging:paging-compose:1.0.0-alpha18
,该版本没有任何变化。版本 1.0.0-alpha18 中包含这些提交内容。
版本 1.0.0-alpha17
2022 年 10 月 24 日
发布了 androidx.paging:paging-compose:1.0.0-alpha17
。版本 1.0.0-alpha17 中包含这些提交内容。
新功能
- 在调用
collectLazyPagingItems
时,添加了对自定义CoroutineContext
的支持。(I7a574、b/243182795、b/233783862)
版本 1.0.0-alpha16
2022 年 8 月 10 日
发布了 androidx.paging:paging-compose:1.0.0-alpha16
。版本 1.0.0-alpha16 中包含这些提交内容。
新功能
- Paging 现在通过
LazyPagingItems
类提供日志,以公开从 PagingData 收集的调试信息。 - 日志可通过
adb shell
命令adb shell setprop log.tag.Paging [DEBUG|VERBOSE]
启用。([b/235527159}(https://issuetracker.google.com/issues/235527159))
bug 修复
- 修复了将
paging-compose:1.0.0-alpha15
与paging-common:3.1.1
或更低版本一起使用时缺少PagingDataDiffer
构造函数的错误。(b/235256201、b/239868768)
版本 1.0.0-alpha15
2022 年 6 月 1 日
发布了 androidx.paging:paging-compose:1.0.0-alpha15
。版本 1.0.0-alpha15 中包含这些提交内容。
API 变更
- 为
PagingDataAdapter
和AsyncPagingDataDiffer
添加了构造函数,它们接受CoroutineContext
,而不是CoroutineDispatcher
。(Idc878)
bug 修复
LazyPagingItems
现在将初始loadState
设置为具有LoadState.Loading
刷新。(I55043、b/224855902)
版本 1.0.0-alpha14
2021 年 10 月 13 日
发布了 androidx.paging:paging-compose:1.0.0-alpha14
。版本 1.0.0-alpha14 中包含这些提交内容。
版本 1.0.0-alpha13
2021 年 9 月 29 日
发布了 androidx.paging:paging-compose:1.0.0-alpha13
。版本 1.0.0-alpha13 中包含这些提交内容。
API 变更
LazyPagingItems.snapshot()
函数已替换为LazyPagingItems.itemSnapshotList
属性 (Ie2da8)- 移除了已弃用的
LazyPagingItems.getAsState()
(Ie65e4)
版本 1.0.0-alpha12
2021 年 7 月 21 日
发布了 androidx.paging:paging-compose:1.0.0-alpha12
。版本 1.0.0-alpha12 中包含这些提交内容。
API 变更
- 用于将 Paging 与
LazyColumn/Row
相关联的items(lazyPagingItems)
和itemsIndexed(lazyPagingItems)
现在会接受选项键参数,您可以使用此参数来指定表示该项的稳定键。您可以在此处详细了解有关键的信息。(I7986d) lazyPagingItems.getAsState(index)
函数现已废弃。已改用lazyPagingItems[index]
。(I086cb、b/187339372)
版本 1.0.0-alpha11
2021 年 6 月 30 日
发布了 androidx.paging:paging-compose:1.0.0-alpha11
。版本 1.0.0-alpha11 中包含这些提交内容。
版本 1.0.0-alpha10
2021 年 6 月 2 日
发布了 androidx.paging:paging-compose:1.0.0-alpha10
。版本 1.0.0-alpha10 中包含这些提交内容。
版本 1.0.0-alpha09
2021 年 5 月 18 日
发布了 androidx.paging:paging-compose:1.0.0-alpha09
。版本 1.0.0-alpha09 中包含这些提交内容。
bug 修复
- LazyPagingItems 的 itemCount 和项 getter 现在是可观察的,因而可与 LazyVerticalGrid 搭配使用(Ie2446、b/171872064、b/168285687)
Compose 兼容性
androidx.paging:paging-compose:1.0.0-alpha09
仅与 Compose 版本1.0.0-beta07
及更高版本兼容。
版本 1.0.0-alpha08
2021 年 2 月 24 日
发布了 androidx.paging:paging-compose:1.0.0-alpha08
。版本 1.0.0-alpha08 中包含这些提交内容。
进行了更新,以便与 Compose 1.0.0-beta01 集成。
版本 1.0.0-alpha07
2021 年 2 月 10 日
发布了 androidx.paging:paging-compose:1.0.0-alpha07
。版本 1.0.0-alpha07 中包含这些提交内容。
进行了更新,以与 Compose alpha12 集成。
版本 1.0.0-alpha06
2021 年 1 月 28 日
发布了 androidx.paging:paging-compose:1.0.0-alpha06
。版本 1.0.0-alpha06 中包含这些提交内容。
bug 修复
进行了更新,以依赖 Compose 1.0.0-alpha11。
版本 1.0.0-alpha05
2021 年 1 月 13 日
发布了 androidx.paging:paging-compose:1.0.0-alpha05
。版本 1.0.0-alpha05 中包含这些提交内容。
进行了更新,以依赖 Compose 1.0.0-alpha10。
版本 1.0.0-alpha04
2020 年 12 月 16 日
发布了 androidx.paging:paging-compose:1.0.0-alpha04
。版本 1.0.0-alpha04 中包含这些提交内容。
bug 修复
- 更新了便捷属性
CombinedLoadStates.refresh
、CombinedLoadStates.prepend
、CombinedLoadStates.append
,让它们仅能在 mediator 和 source 加载状态均为NotLoading
之后才能从Loading
转换到NotLoading
,以确保远程更新得以应用。(I65619)
版本 1.0.0-alpha03
2020 年 12 月 2 日
发布了 androidx.paging:paging-compose:1.0.0-alpha03
。版本 1.0.0-alpha03 中包含这些提交内容。
- 进行了更新,以匹配 Compose 1.0.0-alpha08。
版本 1.0.0-alpha02
2020 年 11 月 11 日
发布了 androidx.paging:paging-compose:1.0.0-alpha02
。版本 1.0.0-alpha02 中包含这些提交内容。
API 变更
- 向
LazyPagingItem
s 添加了.peek()
、.snapshot()
、.retry()
和.refresh()
方法,从而与AsyncPagingDataDiffer
/PagingDataAdapter
提供相同的功能( Iddfe8、b/172041660)
版本 1.0.0-alpha01
2020 年 10 月 28 日
发布了 androidx.paging:paging-compose:1.0.0-alpha01
。版本 1.0.0-alpha01 中包含这些提交内容。
新功能
paging-compose
工件提供了 Paging 库和 Jetpack Compose 之间的集成。简单的用法示例:
@Composable
@OptIn(ExperimentalLazyDsl::class)
fun ItemsDemo(flow: Flow<PagingData<String>>) {
val lazyPagingItems = flow.collectAsLazyPagingItems()
LazyColumn {
items(lazyPagingItems) {
Text("Item is $it")
}
}
}
版本 3.0.1
版本 3.0.1
2021 年 7 月 21 日
发布了 androidx.paging:paging-*:3.0.1
。版本 3.0.1 中包含这些提交内容。
bug 修复
- 从
LivePagedList
或RxPagedList
生成的初始值访问PagedList.dataSource
不会再错误地抛出 IllegalStateException 错误 (I96707)
版本 3.0.0
版本 3.0.0
2021 年 5 月 5 日
发布了 androidx.paging:paging-*:3.0.0
。版本 3.0.0 中包含这些提交内容。
3.0.0 的主要功能
Paging 2.xx 中的大多数现有 API 已废弃,取而代之的是新的 Paging 3 API,这些 API 带来了以下改进:
- 为 Kotlin 协程和流程提供一流的支持
- 支持取消
- 内置加载状态和错误信号
- 重试 + 刷新功能
- 将三个 DataSource 子类合并成了一个统一的 PagingSource 类
- 自定义页面转换,其中包括用于添加分隔符的内置转换
- 加载状态页眉和页脚
版本 3.0.0-rc01
2021 年 4 月 21 日
发布了 androidx.paging:paging-*:3.0.0-rc01
。版本 3.0.0-rc01 中包含这些提交内容。
bug 修复
- 修复了 Paging 有时会向 RecyclerView 发送空操作差异事件的问题,这个问题可能会导致某些监听器提前触发。(Ic507f、b/182510751)
版本 3.0.0-beta03
2021 年 3 月 24 日
发布了 androidx.paging:paging-*:3.0.0-beta03
。版本 3.0.0-beta03 中包含这些提交内容。
bug 修复
- 我们精心改进了重新加载列表时处理占位符的方式,以防止 RecyclerView 中出现意外跳转。如需了解详情,请参阅 NullP addedDiffing.md。(If1490、b/170027529、b/177338149)
- 调用
.build()
时,各种 PagedList 构建器(旧兼容性路径)不会再错误地在主线程上同步调用DataSource.Factory.create()
。(b/182798948)
版本 3.0.0-beta02
2021 年 3 月 10 日
发布了 androidx.paging:paging-*:3.0.0-beta02
。版本 3.0.0-beta02 中包含这些提交内容。
API 变更
- Rx3 扩展现在会正确地传播
@ExperimentalCoroutinesApi
“选择启用”要求。以前,Rx3 扩展是在@get
方法中进行标记的,但该方法会被 Kotlin 编译器忽略,原因如下:https://youtrack.jetbrains.com/issue/KT-45227 (I5733c)
bug 修复
- 对实验性 API 的公开使用施加了限制(I6aa29、b/174531520)
- 修复了以下 bug:在调用远程刷新时,会导致
PagingState
始终为null
。 - 修复了以下 bug:PagingSource 返回的空白页可能会使 Paging 无法再次提取相应信息以执行
prefetchDistance
,从而导致 Paging“卡住”。
版本 3.0.0-beta01
2021 年 2 月 10 日
发布了 androidx.paging:paging-*:3.0.0-beta01
。版本 3.0.0-beta01 中包含这些提交内容。
API 变更
- Rx2 和 Rx3 封装容器现在会公开它所依赖的实验性注解。如果您在 paging-rxjava2 或 paging-rxjava3 中使用 Rx compat 封装容器,则现在需要使用
@OptIn(ExperimentalCoroutinesApi::class)
为使用情况添加注解 (Ib1f9d)
bug 修复
- 修复了在通过兼容性路径使用 v2
DataSource
API 时有时会抛出IndexOutOfBoundsException: Inconsistency detected
的问题 - 当通过兼容性路径使用
DataSource
时,DataSource 初始化期间的isInvalid
调用现在会正确地在 fetchDispatcher 上(而不是在主线程上)启动。这修复了在使用 Room 的PagingSource
实现时,由于在主线程上访问 Db 而产生的IllegalStateException
问题。
版本 3.0.0-alpha13
2021 年 1 月 27 日
发布了 androidx.paging:paging-*:3.0.0-alpha13
。版本 3.0.0-alpha13 中包含这些提交内容。
API 变更
PagingSource.getRefreshKey
不再是可选实现,而是没有默认实现的抽象函数。迁移用户可以继续返回默认实现(仅返回null
),但getRefreshKey()
应具有基于用户当前滚动位置返回按键的真实实现,以在可能的情况下使 Paging 能够通过PagingState.anchorPosition
以视口为中心继续进行加载。(I4339a)InvalidatingPagingSourceFactory
现在是最终类 (Ia3b0a)- 允许使用额外的可选 SeparatorType 参数配置终端分隔符(页眉/页脚)行为。两个选项为:
FULLY_COMPLETE
- 现有行为;先等待 PagingSource 和 RemoteMediator 标记 endOfPaginationReached,然后再添加终端分隔符。如果未使用 RemoteMediator,则会忽略远程 loadState。此选项主要适用于以下情况:您只想在完全加载(包括从网络等远程来源提取)某个部分后显示部分分隔符。SOURCE_COMPLETE
- 仅等待 PagingSource 标记 endOfPaginationReached,即使使用了 RemoteMediator。这使得页眉和页脚可与初始加载内容同步显示,从而使用户无需滚动即可查看终端分隔符。(Ibe993、b/174700218)
bug 修复
- 修复了在以下情况下发生的罕见内存泄漏:PagingSource 在 PageFetcher 可以开始从 PagingSource 加载之前就已无效。(I9606b、b/174625633)
版本 3.0.0-alpha12
2021 年 1 月 13 日
发布了 androidx.paging:paging-*:3.0.0-alpha12
。版本 3.0.0-alpha12 中包含这些提交内容。
API 变更
- InvalidatingPagingSourceFactory 不再是抽象类,因为它从来都没有任何抽象方法。(I4a8c4)
- 针对 Java 用户添加了接受 ViewModel 而非 Lifecycle 或 CoroutineScope 的 .cachedIn() 重载。(I97d81、b/175332619)
- 通过在转换运算符参数中接受执行器,允许 Java 调用方以异步方式使用 PagingData 转换操作。所有 -Sync 转换运算符现在都移除了 -Sync 后缀,Kotlin 协程用户需要改为调用接受挂起代码块的扩展函数来消除歧义。所有 PagingData 转换运算符已移至静态 PagingDataTransforms 类下的扩展中。Java 用户需要通过静态辅助程序(例如
PagingDataTransforms.map(pagingData, transform)
)来调用它们。对于 Kotlin 用户,虽然语法相同,但您需要导入该函数。(If6885、b/172895919)
bug 修复
- 修复了以下 bug:在
adapter.refresh()
期间,如果已到达分页结束处,就不会调用RemoteMediator.load()
。
版本 3.0.0-alpha11
2020 年 12 月 16 日
发布了 androidx.paging:paging-*:3.0.0-alpha11
。版本 3.0.0-alpha11 中包含这些提交内容。
新功能
- 为以下基本用例添加了对“已保存状态”的支持(完全支持,尤其在分层来源用例正在执行过程中时):
- 流数据已缓存且应用未终止(例如:流数据已缓存在视图模型中,activity 正在重新创建)
- Paging 来源已统计,占位符已启用,且布局未交错。
API 变更
PagingSource.getRefreshKey()
现已是稳定的 API(I22f6f、b/173530980)PagingSource.invalidate
不再是开放函数。如果您需要在无效情况发生时收到通知,请考虑调用 registerInvalidatedCallback 方法,而不是替换 invalidate。(I628d9、b/173029013、b/137971356)- 除了常规构造函数外,Pager 现在有了一个单独的实验性构造函数;而不是通过选择启用注解,将实验性 API 泄漏到非实验性公共 API 中。(I9dc61、b/174531520)
- 更新了便捷属性
CombinedLoadStates.refresh
、CombinedLoadStates.prepend
、CombinedLoadStates.append
,让它们仅能在 mediator 和 source 加载状态均为NotLoading
之后才能从Loading
转换到NotLoading
,以确保远程更新得以应用。(I65619) 移除了 LoadParams.pageSize(已被弃用)。建议您在 PagingSource 中使用
LoadParams.loadSize
。LoadParams.loadSize
始终等于PagingConfig.pageSize
(初始加载调用时除外,此时它等于PagingConfig.initialLoadSize
)。当您在不使用 Pager 或 PagedList 的情况下测试您的 Paging2 DataSource 时,如果您还设置了
initialLoadSize
,pageSize
就可能会与PagingConfig.pageSize
不一致。如果这对您的测试非常重要,请尝试改用 Pager/PagedList,它将在内部为您的 DataSource 加载方法设置正确的 PageSize。(I98ac7、b/149157296)
bug 修复
- 修复了以下问题:在 PagingConfig.maxSize 已设置的情况下,使用分隔符时会因 IllegalStateException 而出现崩溃。(I0ed33、b/174787528)
- 修复了以下 bug:如果已设置 RemoteMediator,那么 PREPEND/APPEND 的加载状态便不会在初始加载后立即更新为
NotLoading(endOfPaginationReached = true)
(I8cf5a) - 修复了以下 bug:.snapshot()、.peek() 等演示者端 API 会返回 ListUpdateCallback 更新内的上一个(已过时)列表。
- 修复了以下 bug:分隔符与 RemoteMediator 搭配使用时,不会添加页眉或页脚
- 修复了以下 bug:RemoteMediator 的 LoadState 更新为 NotLoading 时,会卡在 Loading 状态
- 修复了以下 bug:Paging2.0 兼容性 API
.asPagingSourceFactory()
可能会导致备用DataSource
在不正确的 CoroutineDispatcher 上初始化。此错误修复解决了崩溃问题和可能发生的 ANR 问题,尤其可避免在使用 Room 的当前 PagingSource 实现(使用此兼容性路径)时发生这些问题。
版本 3.0.0-alpha10
2020 年 12 月 2 日
发布了 androidx.paging:paging-*:3.0.0-alpha10
。版本 3.0.0-alpha10 中包含这些提交内容。
API 变更
移除了已废弃的
dataRefreshFlow
和dataRefreshListener
API,因为这些 API 与 loadStateFlow/Listener 更新重复了。对于此类迁移,loadStateFlow 相当于:loadStateFlow.distinctUntilChangedBy { it.refresh } .filter { it.refresh is NotLoading }
bug 修复
- RemoteMediator
REFRESH
的 endOfPaginationReached 现在会正确地传播到 LoadState 更新,并会防止触发远程APPEND
和PREPEND
。(I94a3f、b/155290248) - 在因初始页为空或过滤条件过于严苛而导致显示空列表时,将不再导致 Paging 无法开始加载
PREPEND
或APPEND
。(I3e702、b/168169730) - 修复了以下问题:当无效情况急速发生时,后续生成的 PagingSource 不调用
getRefreshKey
。(I45460、b/170027530)
外部贡献
- 添加了新的抽象类 InvalidatingPagingSourceFactory,并附带
.invalidate()
API,该 API 会将无效信号转发给它发出的所有 PagingSource。感谢 @claraf3!(Ie71fc、b/160716447)
已知问题
- 通过 .insertSeparators() 转换得出的页眉和页脚可能不会在使用 RemoteMediator 时立即显示 b/172254056
- 如果在
RemoteMediator.load()
返回前便发生了无效情况且PagingSource.load(LoadParams.Refresh(...))
已运行完毕,那么使用 RemoteMediator 可能会导致远程LoadState
卡住 b/173717820
版本 3.0.0-alpha09
2020 年 11 月 11 日
发布了 androidx.paging:paging-*:3.0.0-alpha09
。版本 3.0.0-alpha09 中包含这些提交内容。
API 变更
- 完全弃用 dataRefreshFlow/Listener 方法,改用 replaceWith 子句。(I6e2dd)
bug 修复
- 在对 RemoteMediator 使用分隔符时,在会返回 endOfPagination 的远程加载仍在运行时触发了 invalidate 的情况下会抛出
IllegalArgumentException
,现在修复了这个问题 (I3a260)
版本 3.0.0-alpha08
2020 年 10 月 28 日
发布了 androidx.paging:paging-*:3.0.0-alpha08
。版本 3.0.0-alpha08 中包含这些提交内容。
API 变更
- 通过功能接口(在 Kotlin 1.4 中提供)启用了 SAM 转化,从而合并了
DataSource.InvalidatedCallback
的 Kotlin/Java 变体。这也修复了无效回调的 Kotlin 变体在被.map
或.mapByPage
转换后没有被调用的 bug。(I1f244、b/165313046)
bug 修复
- Paging 与 ViewPager 的交互已得到显著改善。具体而言,Paging 不会再因页面失效而取消
RemoteMediator#load
调用。如果需要进行 REFRESH,Paging 也不会再发出附加/前置加载请求,直到 REFRESH 请求成功完成为止。(I6390b、b/162252536) - 针对 androidx 启用了 MissingGetterMatchingBuilder 的 API lint 检查(I4bbea、b/138602561)
- 修复了以下 bug:在从后台线程通知 RecyclerView 时,
.withLoadState*
ConcatAdapter
帮助程序会发生崩溃(I18bb5、b/170988309) - 修复了加载超小非空页面有时会导致预提取无法正确触发加载的 bug。Iffda3 b/169259468
版本 3.0.0-alpha07
2020 年 10 月 1 日
发布了 androidx.paging:paging-*:3.0.0-alpha07
。版本 3.0.0-alpha07 中包含这些提交内容。
API 变更
- 基于 Guava 的异步 PagingData 运算符现在接受 Executor 作为参数,以控制执行环境。(Id4372)
bug 修复
- 修复了因竞态条件导致 RemoteMediator 中抛出 IndexOutOfBounds 异常的问题。(I00b7f、b/165821814)
- 修复了 DataSource 向 PagingSource 转换过程中发生的竞态条件,该问题可能会导致生成的 PagingSource 忽略来自 DataSource 的无效信号。
- 修复了页面 fetchin 逻辑中的一个问题,该问题有时会导致在系统调用 PagingDataAdapter.refresh() 之前,该逻辑无法提取新生成的 PagingSource
- 修复了可能导致以下情况的问题:当结合使用已转换成 PagingSource(例如由 Room 生成的 PagingSource)的 DataSource 与 RemoteMediator 时,滚动位置有时会丢失。
外部贡献
- 感谢 @simonschiller 为 PagingData 添加了 RxJava2、RxJava3 和基于 Guava 的异步转换运算符!
版本 3.0.0-alpha06
2020 年 9 月 2 日
发布了 androidx.paging:paging-*:3.0.0-alpha06
。版本 3.0.0-alpha06 中包含这些提交内容。
API 变更
- 现在,只要调用
PagingDataAdapter.setHasStableIds
便会抛出UnsupportedOperationException
,并会显示更明确的信息来说明不支持稳定 ID。(Ib3890、b/158801427)
bug 修复
- insertSeparators 不再过滤出空白页,以便 Presenter 遵从预取距离,即使在插入多个空白页的情况下也是如此。(I9cff6、b/162538908)
版本 3.0.0-alpha05
2020 年 8 月 19 日
发布了 androidx.paging:paging-*:3.0.0-alpha05
。版本 3.0.0-alpha05 中包含这些提交内容。
bug 修复
- Paging 现在可以正确地预提取页面,即使呈现的数据经过很大程度的过滤也不例外
- 向重试的加载返回
LoadResult.Error
不会再导致项访问错误地重新触发重试
外部贡献
- 感谢 Clara F 帮助清理了一些测试!(549612)
版本 3.0.0-alpha04
2020 年 8 月 5 日
发布了 androidx.paging:paging-*:3.0.0-alpha04
。版本 3.0.0-alpha04 中包含这些提交内容。
API 变更
- 在
AsyncPagingDataDiffer
和PagingDataAdapter
中添加了peek()
API,以允许在不触发页面加载的情况下访问所提供的数据。(I38898、b/159104197) - 在
PagingDataAdapter
和AsyncPagingDataDiffer
中添加了snapshot()
API,以允许在不触发页面提取的情况下检索提供的项。(I566b6、b/159104197) - 添加了
PagingData.from(List<T>)
构造函数以允许显示静态列表,该列表可与总体 PagingData 流组合使用以在特定状态(例如,在初始 REFRESH 操作完成之前或仅用于测试转换时)显示静态列表。(Id134d) - 弃用了 dataRefresh 流/侦听器 API,因为它们用于在 REFRESH 上公开所提供的项状态,但由于我们改进了 loadState 流/侦听器回调时机和 itemCount 属性,现在已不需要 dataRefresh 流/侦听器 API (Ia19f3)
- 为
PagingSource
和RemoteMediator
添加了 RxJava3 兼容性封装容器(I49ef3、b/161480176)
bug 修复
PositionalDataSource
已通过toPagingSourceFactory
帮助程序转换为PagingSource
,包括由 Room 生成的PagingSource
现在可以正确进行自我标记以支持跳转。(I3e84c、b/162161201)- 修复了如下 bug:使用 submitData 的同步变体有时会导致争用而引发
ClosedSendChannelException
(I4d702、b/160192222)
外部贡献
- 感谢 Zac Sweers 代表 Slack 添加了 RxJava3 兼容性封装容器!(I49ef3、b/161480176)
版本 3.0.0-alpha03
2020 年 7 月 22 日
发布了 androidx.paging:paging-*:3.0.0-alpha03
。版本 3.0.0-alpha03 包含以下提交内容。
API 变更
- PagingState 的构造函数现已成为公共构造函数,这应该会使测试 getRefreshKey() 的实现变得更轻松 (I8bf15)
- DataSource Kotlin 映射函数变体已对 Java 隐藏,目的是消除原始变体与 Kotlin 变体之前的歧义。(If7b23、b/161150011)
- Kotlin 用户专用的冗余 API 已被标记为 @JvmSynthetic (I56ae5)
- 为 LoadResult.Page 的构造函数添加了重载,会将 itemsBefore 和 itemsAfter 默认设置为 COUNT_UNDEFINED (I47849)
- 使现有的 PagingData 运算符接受挂起方法,并为 Java 用户引入了新的非挂起运算符:mapSync、flatMapSync 和 filterSync。现有转换方法已移至扩展函数,因此 Kotlin 用户现在需要导入这些方法。(I34239、b/159983232)
bug 修复
- Room(和 PositionalDataSource)PagingSource 现在会在首个页面中显示前导分隔符,从而无需用户滚动页面就能显示。(I6f747、b/160257628)
- 现在,凭借对占位符的项访问权限,系统可以正确触发 PagingSource 加载;直至返回在经 PagingData.filter() 转换后按要求编入索引的页面时,加载方会停止(I95625、b/158763195)
- 修复了以下 bug:PagingSource 返回错误后页面有时会滚动,可能导致 PagingDataAdapter.retry() 无法执行重试操作。(I1084f、b/160194384)
- 修正了以下问题:尽管项访问权限的作用范围为 prefetchDistance,但在丢弃某个页面后,即使有项访问权限系统也可能不会加载页面(Ie95ae、b/160038730)
- 在发生丢弃事件后,设置“PagingConfig.maxSize”不会再启用占位符(I2be29、b/159667766)
版本 3.0.0-alpha02
2020 年 6 月 24 日
发布了 androidx.paging:paging-*:3.0.0-alpha02
。版本 3.0.0-alpha02 中包含以下提交内容。
API 变更
- 为
PagingConfig
的构造函数(带有常用默认值)添加了重载(I39c50、b/158576040) - 为
PagingDataAdapter
和AsyncPagingDataDiffer
的构造函数(带有常用默认值)添加了重载 (Ie91f5) - 适配器 API
dataRefreshFlow
和dataRefreshListener
现在会传递一个布尔值,以指示PagingData
是否为空(I6e37e、b/159054196) - 为 RemoteMediator(RxRemoteMediator 和 ListenableFutureRemoteMediator)添加了 RxJava 和 Guava API
- 向 PagingState 添加了辅助程序(例如
isEmpty()
和firstItemOrNull()
),以获取通用项访问权限(I3b5b6、b/158892717)
bug 修复
- 分页器现在会检查在工厂中重复使用 PagingSource 的情况,以防意外重复使用无效的 PagingSource(这会导致出现不明确的错误)(I99809、b/158486430)
- RemoteMediator REFRESH 运行失败不会再导致 PagingSource 无法加载(I38b1b、b/158892717)
- 在
submitData
的挂起版本之后调用submitData
的非挂起版本时,后者不再会因多个PagingData
上的并发收集而出现崩溃。(I26358、b/158048877) - 修复了在配置更改后可能发生的“无法从分页器收集两次”异常(I58bcc、b/158784811)
版本 3.0.0-alpha01
2020 年 6 月 10 日
发布了 androidx.paging:paging-*:3.0.0-alpha01
。版本 3.0.0-alpha01 中包含这些提交内容。
Paging 库已更新至 3.0,支持若干项主要的新功能。
3.0 的新功能
- 为 Kotlin 协程和流程提供一流的支持。
- 支持使用协程挂起函数、RxJava Single 或 Guava ListenableFuture 基元进行异步加载。
- 针对自适应界面设计的内置加载状态和错误信号,包括重试和刷新功能。
- 改进了代码库层
- 简化了数据源界面
- 简化了网络 + 数据库分页
- 支持取消功能
- 改进了演示层
已知问题
- Paging 3 Javadoc 尚不可用。在过渡期间,请使用上面给出链接的指南或 Kotlin 文档。(b/158614050)
版本 2.1.2
版本 2.1.2
2020 年 3 月 18 日
发布了 androidx.paging:paging:2.1.2
。版本 2.1.2 包含针对 2.1.0 的这些提交内容。
bug 修复
- 修复了失效期间转换位置时,在极少数情况下出现的
IndexOutOfBoundsException
问题。
版本问题
错误发布了配置有误的分支中的 Paging 版本
2.1.1
,公开了即将在未来版本中推出的未完全实现的 API 和功能。Paging
2.1.2
包含主要针对加载功能的修复,这些内容最初是在 2.1.1 中发布的,但这次在版本 2.1.0 的基础上正确进行了挑选。如果您目前使用的是 2.1.1,强烈建议您升级到此版本。
版本 2.1.1
版本 2.1.1
2019 年 12 月 18 日
发布了 androidx.paging:paging-*:2.1.1
。版本 2.1.1 中包含以下提交内容。
bug 修复
- 停用占位符后,通过 PositionalDataSource 进行的连续初始加载现在会仅仅围绕上次访问执行
版本 2.1.0
版本 2.1.0
2019 年 1 月 25 日
发布了 Paging 2.1.0
,该版本与 2.1.0-rc01
相比没有变化。
版本 2.1.0-rc01
2018 年 12 月 6 日
发布了 Paging 2.1.0-rc01
,该版本与 2.1.0-beta01
相比没有变化。
版本 2.1.0-beta01
2018 年 11 月 1 日
发布了 Paging 2.1.0-beta01
,该版本与 2.1.0-alpha01
相比没有变化。
版本 2.1.0-alpha01
2018 年 10 月 12 日
Paging 2.1.0-alpha01
主要新增了两部分内容,一是页面丢弃,二是为每个工件新增了 KTX 扩展库,此外还进行了另外几项 API 更改,并修复了一些问题。
API 变更
- 添加了
PagedList.Config.Builder.setMaxSize()
,用于限制在内存中加载的项数。 - 添加了
androidx.paging.Config()
作为PagedList.Config.Builder
的 Kotlin 替代方案 - 添加了
androidx.paging.PagedList()
作为PagedList.Builder
的 Kotlin 替代方案 - 添加了
DataSourceFactory.toLiveData()
作为LivePagedListBuilder
的 Kotlin 替代方案 - 添加了
DataSourceFactory.toObservable()
和toFlowable()
作为RxPagedListBuilder
的 Kotlin 替代方案 - 添加了
AsyncPagedListDiffer.addPagedListListener()
,用于监听何时交换 PagedList。b/111698609 - 添加了用于传递新旧列表的
PagedListAdapter.onCurrentListChanged()
变体,弃用了以前的变体。 - 添加了
PagedListAdapter/AsyncPagedListDiffer.submitList()
变体,这些变体在比较差异后接受额外的回调,该回调在显示 pagedlist 时触发。这样,您可以将 PagedList 交换与其他界面更新同步。b/73781068 - 添加了
PagedList.getLoadedCount()
,以告知您内存中有多少项。请注意,如果停用了占位符,则返回值会一律等于.size()
。
bug 修复
- 修复了在重复使用列表的情况下比较差异时的竞态条件问题 b/111591017
- 当索引无效时,
PagedList.loadAround()
现在会抛出IndexOutOfBoundsException
。之前,它可能会发生崩溃,并抛出不明确的其他异常。 - 修复了极小初始负载在数据未更改时导致不再继续加载的问题 b/113122599
版本 2.0.0
版本 2.0.0
2018 年 10 月 1 日
发布了 Paging 2.0.0
,该版本修复了一个 bug。
bug 修复
- 修复了在使用
PositionalDataSource
和占位符的情况下进行非常快速的滚动时可能会发生崩溃的问题。b/114635383
版本 2.0.0-beta01
2018 年 7 月 2 日
bug 修复
- 修复了在某些前置情况下(占位符已停用,PositionalDataSource)内容消失的问题 b/80149146
- (在
1.0.1
中已发布)修复了导致PagedListAdapter
和AsyncPagedListDiffer
无法发出移动事件信号的崩溃问题。b/110711937
AndroidX 之前的依赖项
对于 AndroidX 之前的 Paging 版本,请添加以下依赖项:
dependencies {
def paging_version = "1.0.0"
implementation "android.arch.paging:runtime:$paging_version"
// alternatively - without Android dependencies for testing
testImplementation "android.arch.paging:common:$paging_version"
// optional - RxJava support
implementation "android.arch.paging:rxjava2:$paging_version"
}
版本 1.0.1
版本 1.0.1
2018 年 6 月 26 日
发布了 Paging 1.0.1
,该版本修复了 runtime
中的一个 bug。为了保持稳定性,我们强烈建议使用 1.0.1
。还发布了 Paging RxJava2 1.0.1
,它与 1.0.0-rc1
完全相同。
bug 修复
- 修复了导致
PagedListAdapter
和AsyncPagedListDiffer
无法发出移动事件信号的崩溃问题。b/110711937
RxJava2 版本 1.0.0
RxJava2 版本 1.0.0-rc1
2018 年 5 月 16 日
Paging RxJava2 1.0.0-rc1
即将迁移到候选版本,该版本与初始 alpha 版本相比没有变化。
版本 1.0.0
版本 1.0.0-rc1
2018 年 4 月 19 日 Paging 候选版本
我们没有关于 Paging 1.0.0
版本的任何其他已知问题,也没有为其做新功能方面的安排。请升级您的项目以使用 1.0.0-rc1
并帮助我们对其进行严格的测试,以便我们可以推出稳定可靠的 1.0.0
。
此版本没有任何变化,它与 1.0.0-beta1
相同。
版本 1.0.0-beta1
2018 年 4 月 5 日
在成为候选版本之前,Paging 将在测试阶段进行短时间的测试。
我们不计划对 Paging 1.0
做出进一步的 API 更改,并且任何 API 变更的标准都非常高。
Alpha RxJava2 对 Paging 的支持作为一个单独的可选模块 (android.arch.paging:rxjava2:1.0.0-alpha1
) 发布,并且将暂时单独版本化,直到它稳定为止。
此新库提供了 RxJava2 来替代 LivePagedListBuilder
,能够构造 Observable
和 Flowable
,接受 Scheduler
而不是 Executor
:
Kotlin
val pagedItems = RxPagedListBuilder(myDataSource, /* page size */ 50) .setFetchScheduler(myNetworkScheduler) .buildObservable()
Java
Observable<PagedList<Item>> pagedItems = RxPagedListBuilder(myDataSource, /* page size */ 50) .setFetchScheduler(myNetworkScheduler) .buildObservable();
新功能
- 通过新的
android.arch.paging:rxjava2
工件添加了RxPagedListBuilder
。
API 变更
进行了 API 变更,以阐明执行器在构建器中的作用:
(在
PagedList.Builder
和LivePagedListBuilder
中)将setBackgroundThreadExecutor()
重命名为setFetchExecutor()
(在
PagedList.Builder
中)将setMainThreadExecutor()
重命名为setNotifyExecutor()
。
修复了
PagedList.mCallbacks
成员,使其成为私有成员。
bug 修复
LivePagedListBuilder
将在指定的执行器上(而不是在架构组件 IO 线程池中)触发初始PagedList
加载。修复了内部
DataSource
封装容器(用于实现DataSource.map
以及停用了占位符的PositionalDataSource
加载)中的失效行为 b/77237534
版本 1.0.0-alpha7
2018 年 3 月 21 日
发布了 Paging 1.0.0-alpha7
以及 Lifecycles 1.1.1
。由于 Paging alpha7 依赖于上述 Function
类的移动,因此您需要将 lifecycle:runtime
依赖项更新为 android.arch.lifecycle:runtime:1.1.1
。
在 Paging 进入测试阶段之前,计划将 Paging alpha7
作为最终版本。
API 变更
DataSource.LoadParams
对象现在具有一个公开构造函数,而DataSource.LoadCallback
对象现在是抽象对象。 这样,便可以封装DataSource
或通过模拟回调直接测试DataSource
。b/72600421- DataSource 和 DataSource.Factory 的映射器
- 通过
map(Function<IN,OUT>)
,可以转换、封装或修饰由DataSource
加载的结果。 mapByPage(<List<IN>,List<OUT>>)
可以为批处理启用相同的功能(例如,如果从 SQL 加载的项需要另外查询一个单独的数据库,则可以采用批处理的方式完成该操作)。
- 通过
- 以便捷方法的形式添加了
PagedList#getDataSource()
b/72611341 - 从 API 中移除了所有已弃用的类,包括
recyclerview.extensions
软件包的剩余内容和LivePagedListProvider
。 DataSource.Factory
从接口更改为抽象类以启用映射功能。
bug 修复
- 构建器已更改为最终版本。 b/70848565
- 现修复了 Room
DataSource
实现,使其能够处理多表查询 - 此修复包含在 Room 1.1.0-beta1 中,参见上文。 - 修复了在启用占位符后且总大小为页面大小的整数倍时无法为
PositionalDataSource
调用BoundaryCallback.onItemAtEndLoaded
的 bug。
版本 1.0.0-alpha5
2018 年 1 月 22 日
bug 修复
- 修复了停用占位符后的页面加载问题 b/70573345
- 添加了跟踪 IllegalArgumentException bug 的日志记录 b/70360195(以及推测性 Room 端修复)
- 修复了 Javadoc 示例代码 b/70411933 和 b/71467637