AsyncPagingDataDiffer
-
android
class AsyncPagingDataDiffer<T : Any>
Helper class for mapping a PagingData
into a RecyclerView.Adapter
.
For simplicity, PagingDataAdapter
can often be used in place of this class. AsyncPagingDataDiffer
is exposed for complex cases, and where overriding PagingDataAdapter
to support paging isn't convenient.
Summary
Public constructors |
|
---|---|
<T : Any> AsyncPagingDataDiffer( |
android
|
Public functions |
||
---|---|---|
Unit |
addLoadStateListener(listener: (CombinedLoadStates) -> Unit) Add a |
android
|
Unit |
addOnPagesUpdatedListener(listener: () -> Unit) Add a listener which triggers after the pages presented to the UI are updated, even if the actual items presented don't change. |
android
|
T? |
@MainThread Get the item from the current PagedList at the specified index. |
android
|
T? |
@MainThread Returns the presented item at the specified position, without notifying Paging of the item access that would normally trigger page loads. |
android
|
Unit |
refresh() Refresh the data presented by this |
android
|
Unit |
removeLoadStateListener(listener: (CombinedLoadStates) -> Unit) Remove a previously registered |
android
|
Unit |
removeOnPagesUpdatedListener(listener: () -> Unit) Remove a previously registered listener for new |
android
|
Unit |
retry() Retry any failed load requests that would result in a |
android
|
ItemSnapshotList<T> |
snapshot() Returns a new |
android
|
suspend Unit |
submitData(pagingData: PagingData<T>) Present a |
android
|
Unit |
submitData(lifecycle: Lifecycle, pagingData: PagingData<T>) Present a |
android
|
Public properties |
||
---|---|---|
Int |
Get the number of items currently presented by this Differ. |
android
|
Flow<CombinedLoadStates> |
A hot |
android
|
Flow<Unit> |
A hot |
android
|
Public constructors
AsyncPagingDataDiffer
<T : Any> AsyncPagingDataDiffer(
diffCallback: DiffUtil.ItemCallback<T>,
updateCallback: ListUpdateCallback,
mainDispatcher: CoroutineContext = Dispatchers.Main,
workerDispatcher: CoroutineContext = Dispatchers.Default
)
Public functions
addLoadStateListener
fun addLoadStateListener(listener: (CombinedLoadStates) -> Unit): Unit
Add a CombinedLoadStates
listener to observe the loading state of the current PagingData
.
As new PagingData
generations are submitted and displayed, the listener will be notified to reflect the current CombinedLoadStates
.
import androidx.paging.LoadState val adapter = UserPagingAdapter() adapter.addLoadStateListener { // show a retry button outside the list when refresh hits an error retryButton.isVisible = it.refresh is LoadState.Error // swipeRefreshLayout displays whether refresh is occurring swipeRefreshLayout.isRefreshing = it.refresh is LoadState.Loading // show an empty state over the list when loading initially, before items are loaded emptyState.isVisible = it.refresh is LoadState.Loading && adapter.itemCount == 0 }
Parameters | |
---|---|
listener: (CombinedLoadStates) -> Unit |
|
See also | |
---|---|
removeLoadStateListener |
addOnPagesUpdatedListener
fun addOnPagesUpdatedListener(listener: () -> Unit): Unit
Add a listener which triggers after the pages presented to the UI are updated, even if the actual items presented don't change.
An update is triggered from one of the following:
-
submitData
is called and initial load completes, regardless of any differences in the loaded data -
A
Page
is inserted -
A
Page
is dropped
Parameters | |
---|---|
listener: () -> Unit |
called after pages presented are updated. |
See also | |
---|---|
removeOnPagesUpdatedListener |
getItem
@MainThread
fun getItem(index: @IntRange(from = 0) Int): T?
Get the item from the current PagedList at the specified index.
Note that this operates on both loaded items and null padding within the PagedList.
Returns | |
---|---|
T? |
The item, or |
peek
@MainThread
fun peek(index: @IntRange(from = 0) Int): T?
Returns the presented item at the specified position, without notifying Paging of the item access that would normally trigger page loads.
Parameters | |
---|---|
index: @IntRange(from = 0) Int |
Index of the presented item to return, including placeholders. |
Returns | |
---|---|
T? |
The presented item at position |
refresh
fun refresh(): Unit
Refresh the data presented by this AsyncPagingDataDiffer
.
refresh
triggers the creation of a new PagingData
with a new instance of PagingSource
to represent an updated snapshot of the backing dataset. If a RemoteMediator
is set, calling refresh
will also trigger a call to RemoteMediator.load
with LoadType
to allow RemoteMediator
to check for updates to the dataset backing PagingSource
.
Note: This API is intended for UI-driven refresh signals, such as swipe-to-refresh. Invalidation due repository-layer signals, such as DB-updates, should instead use PagingSource.invalidate
.
import androidx.appcompat.app.AppCompatActivity import androidx.paging.LoadState class MyActivity : AppCompatActivity() { private lateinit var binding: MyActivityBinding private val pagingAdapter = UserPagingAdapter() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = MyActivityBinding.inflate(layoutInflater) setContentView(binding.root) binding.recyclerView.adapter = pagingAdapter pagingAdapter.addLoadStateListener { loadStates -> binding.swipeRefreshLayout.isRefreshing = loadStates.refresh is LoadState.Loading } binding.swipeRefreshLayout.setOnRefreshListener { pagingAdapter.refresh() } } }
See also | |
---|---|
invalidate |
removeLoadStateListener
fun removeLoadStateListener(listener: (CombinedLoadStates) -> Unit): Unit
Remove a previously registered CombinedLoadStates
listener.
Parameters | |
---|---|
listener: (CombinedLoadStates) -> Unit |
Previously registered listener. |
See also | |
---|---|
addLoadStateListener |
removeOnPagesUpdatedListener
fun removeOnPagesUpdatedListener(listener: () -> Unit): Unit
Remove a previously registered listener for new PagingData
generations completing initial load and presenting to the UI.
Parameters | |
---|---|
listener: () -> Unit |
Previously registered listener. |
See also | |
---|---|
addOnPagesUpdatedListener |
retry
fun retry(): Unit
Retry any failed load requests that would result in a LoadState.Error
update to this AsyncPagingDataDiffer
.
Unlike refresh
, this does not invalidate PagingSource
, it only retries failed loads within the same generation of PagingData
.
LoadState.Error
can be generated from two types of load requests:
snapshot
fun snapshot(): ItemSnapshotList<T>
Returns a new ItemSnapshotList
representing the currently presented items, including any placeholders if they are enabled.
submitData
suspend fun submitData(pagingData: PagingData<T>): Unit
Present a PagingData
until it is invalidated by a call to refresh
or PagingSource.invalidate
.
This method is typically used when collecting from a Flow
produced by Pager
. For RxJava or LiveData support, use the non-suspending overload of submitData
, which accepts a Lifecycle
.
Note: This method suspends while it is actively presenting page loads from a PagingData
, until the PagingData
is invalidated. Although cancellation will propagate to this call automatically, collecting from a Pager.flow
with the intention of presenting the most up-to-date representation of your backing dataset should typically be done using collectLatest
.
See also | |
---|---|
Pager |
submitData
fun submitData(lifecycle: Lifecycle, pagingData: PagingData<T>): Unit
Present a PagingData
until it is either invalidated or another call to submitData
is made.
This method is typically used when observing a RxJava or LiveData stream produced by Pager
. For Flow
support, use the suspending overload of submitData
, which automates cancellation via CoroutineScope
instead of relying of Lifecycle
.
See also | |
---|---|
submitData |
|
Pager |
Public properties
itemCount
val itemCount: Int
Get the number of items currently presented by this Differ. This value can be directly returned to androidx.recyclerview.widget.RecyclerView.Adapter.getItemCount
.
Returns | |
---|---|
Int |
Number of items being presented, including placeholders. |
loadStateFlow
val loadStateFlow: Flow<CombinedLoadStates>
A hot Flow
of CombinedLoadStates
that emits a snapshot whenever the loading state of the current PagingData
changes.
This flow is conflated, so it buffers the last update to CombinedLoadStates
and delivers the current load states on collection when RecyclerView is not dispatching layout.
import androidx.lifecycle.lifecycleScope import androidx.paging.LoadState val adapter = UserPagingAdapter() lifecycleScope.launch { adapter.loadStateFlow .map { it.refresh } .distinctUntilChanged() .collectLatest { // show a retry button outside the list when refresh hits an error retryButton.isVisible = it is LoadState.Error // swipeRefreshLayout displays whether refresh is occurring swipeRefreshLayout.isRefreshing = it is LoadState.Loading // show an empty state over the list when loading initially, before items are loaded emptyState.isVisible = it is LoadState.Loading && adapter.itemCount == 0 } }
onPagesUpdatedFlow
val onPagesUpdatedFlow: Flow<Unit>
A hot Flow
that emits after the pages presented to the UI are updated, even if the actual items presented don't change.
An update is triggered from one of the following:
-
submitData
is called and initial load completes, regardless of any differences in the loaded data -
A
Page
is inserted -
A
Page
is dropped
Note: This is a SharedFlow
configured to replay 0 items with a buffer of size 64. If a collector lags behind page updates, it may trigger multiple times for each intermediate update that was presented while your collector was still working. To avoid this behavior, you can conflate
this Flow
so that you only receive the latest update, which is useful in cases where you are simply updating UI and don't care about tracking the exact number of page updates.