Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

PagingDataAdapter

abstract class PagingDataAdapter<T : Any, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>
kotlin.Any
   ↳ androidx.recyclerview.widget.RecyclerView.Adapter<VH>
   ↳ androidx.paging.PagingDataAdapter

RecyclerView.Adapter base class for presenting paged data from PagingDatas in a RecyclerView.

This class is a convenience wrapper around AsyncPagingDataDiffer that implements common default behavior for item counting, and listening to update events.

To present a Pager, use collectLatest to observe Pager.flow and call submitData whenever a new PagingData is emitted.

If using RxJava and LiveData extensions on Pager, use the non-suspending overload of submitData, which accepts a Lifecycle.

PagingDataAdapter listens to internal PagingData loading events as pages are loaded, and uses DiffUtil on a background thread to compute fine grained updates as updated content in the form of new PagingData objects are received.


val USER_COMPARATOR = object : DiffUtil.ItemCallback<User>() {
    override fun areItemsTheSame(oldItem: User, newItem: User): Boolean =
        // User ID serves as unique ID
        oldItem.userId == newItem.userId

    override fun areContentsTheSame(oldItem: User, newItem: User): Boolean =
        // Compare full contents (note: Java users should call .equals())
        oldItem == newItem
}

class UserAdapter : PagingDataAdapter<User, UserViewHolder>(USER_COMPARATOR) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        return UserViewHolder.create(parent)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val repoItem = getItem(position)
        // Note that item may be null, ViewHolder must support binding null item as placeholder
        holder.bind(repoItem)
    }
}

Summary

Public constructors
<init>(diffCallback: DiffUtil.ItemCallback<T>, mainDispatcher: CoroutineDispatcher = Dispatchers.Main, workerDispatcher: CoroutineDispatcher = Dispatchers.Default)

RecyclerView.Adapter base class for presenting paged data from PagingDatas in a RecyclerView.

Public methods
Unit
addDataRefreshListener(listener: (isEmpty: Boolean) -> Unit)

Add a listener to observe new PagingData generations.

Unit

Add a CombinedLoadStates listener to observe the loading state of the current PagingData.

open Int

Long
getItemId(position: Int)

Note: getItemId is final, because stable IDs are unnecessary and therefore unsupported.

T?
peek(@IntRange(0) index: Int)

Returns the presented item at the specified position, without notifying Paging of the item access that would normally trigger page loads.

Unit

Refresh the data presented by this PagingDataAdapter.

Unit
removeDataRefreshListener(listener: (isEmpty: Boolean) -> Unit)

Remove a previously registered listener for new PagingData generations.

Unit

Remove a previously registered CombinedLoadStates listener.

Unit

Retry any failed load requests that would result in a LoadState.Error update to this PagingDataAdapter.

Unit
setHasStableIds(hasStableIds: Boolean)

Stable ids are unsupported by PagingDataAdapter.

ItemSnapshotList<T>

Returns a new ItemSnapshotList representing the currently presented items, including any placeholders if they are enabled.

suspend Unit
submitData(pagingData: PagingData<T>)

Present a PagingData until it is invalidated by a call to refresh or PagingSource.invalidate.

Unit
submitData(lifecycle: Lifecycle, pagingData: PagingData<T>)

Present a PagingData until it is either invalidated or another call to submitData is made.

ConcatAdapter

Create a ConcatAdapter with the provided LoadStateAdapters displaying the LoadType.PREPEND as a list item at the start of the presented list.

ConcatAdapter

Create a ConcatAdapter with the provided LoadStateAdapters displaying the LoadType.APPEND as a list item at the end of the presented list.

ConcatAdapter

Create a ConcatAdapter with the provided LoadStateAdapters displaying the LoadType.PREPEND and LoadType.APPENDs as list items at the start and end respectively.

Protected methods
T?
getItem(@IntRange(0) position: Int)

Returns the presented item at the specified position, notifying Paging of the item access to trigger any loads necessary to fulfill prefetchDistance.

Inherited functions
Properties
Flow<Boolean>

A Flow of Boolean that is emitted when new PagingData generations are submitted and displayed.

Flow<CombinedLoadStates>

A hot Flow of CombinedLoadStates that emits a snapshot whenever the loading state of the current PagingData changes.

Public constructors

<init>

PagingDataAdapter(
    diffCallback: DiffUtil.ItemCallback<T>,
    mainDispatcher: CoroutineDispatcher = Dispatchers.Main,
    workerDispatcher: CoroutineDispatcher = Dispatchers.Default)

RecyclerView.Adapter base class for presenting paged data from PagingDatas in a RecyclerView.

This class is a convenience wrapper around AsyncPagingDataDiffer that implements common default behavior for item counting, and listening to update events.

To present a Pager, use collectLatest to observe Pager.flow and call submitData whenever a new PagingData is emitted.

If using RxJava and LiveData extensions on Pager, use the non-suspending overload of submitData, which accepts a Lifecycle.

PagingDataAdapter listens to internal PagingData loading events as pages are loaded, and uses DiffUtil on a background thread to compute fine grained updates as updated content in the form of new PagingData objects are received.


val USER_COMPARATOR = object : DiffUtil.ItemCallback<User>() {
    override fun areItemsTheSame(oldItem: User, newItem: User): Boolean =
        // User ID serves as unique ID
        oldItem.userId == newItem.userId

    override fun areContentsTheSame(oldItem: User, newItem: User): Boolean =
        // Compare full contents (note: Java users should call .equals())
        oldItem == newItem
}

class UserAdapter : PagingDataAdapter<User, UserViewHolder>(USER_COMPARATOR) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        return UserViewHolder.create(parent)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val repoItem = getItem(position)
        // Note that item may be null, ViewHolder must support binding null item as placeholder
        holder.bind(repoItem)
    }
}

Public methods

addDataRefreshListener

fun addDataRefreshListener(listener: (isEmpty: Boolean) -> Unit): Unit

Deprecated.

Add a listener to observe new PagingData generations.

Parameters
listener: (isEmpty: Boolean) -> Unit called whenever a new PagingData is submitted and displayed. true is passed to the listener if the new PagingData is empty, false otherwise.

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.


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 LoadStates listener to receive updates.

getItemCount

open fun getItemCount(): Int

getItemId

fun getItemId(position: Int): Long

Note: getItemId is final, because stable IDs are unnecessary and therefore unsupported.

PagingDataAdapter's async diffing means that efficient change animations are handled for you, without the performance drawbacks of RecyclerView.Adapter.notifyDataSetChanged. Instead, the diffCallback parameter of the PagingDataAdapter serves the same functionality - informing the adapter and RecyclerView how items are changed and moved.

peek

fun peek(@IntRange(0) index: 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: Int Index of the presented item to return, including placeholders.
Return
The presented item at position index, null if it is a placeholder.

refresh

fun refresh(): Unit

Refresh the data presented by this PagingDataAdapter.

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.


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()
        }
    }
}

removeDataRefreshListener

fun removeDataRefreshListener(listener: (isEmpty: Boolean) -> Unit): Unit

Deprecated.

Remove a previously registered listener for new PagingData generations.

Parameters
listener: (isEmpty: Boolean) -> Unit Previously registered listener.

removeLoadStateListener

fun removeLoadStateListener(listener: (CombinedLoadStates) -> Unit): Unit

Remove a previously registered CombinedLoadStates listener.

Parameters
listener: (CombinedLoadStates) -> Unit Previously registered listener.

retry

fun retry(): Unit

Retry any failed load requests that would result in a LoadState.Error update to this PagingDataAdapter.

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:

setHasStableIds

fun setHasStableIds(hasStableIds: Boolean): Unit

Stable ids are unsupported by PagingDataAdapter. Calling this method is an error and will result in an UnsupportedOperationException.

Parameters
hasStableIds: Boolean Whether items in data set have unique identifiers or not.
Exceptions
UnsupportedOperationException Always thrown, since this is unsupported by PagingDataAdapter.

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.

submitData should be called on the same CoroutineDispatcher where updates will be dispatched to UI, typically Dispatchers.Main (this is done for you if you use lifecycleScope.launch {}).

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.

import androidx.activity.viewModels

class MyFlowActivity : AppCompatActivity() {
    val pagingAdapter = UserPagingAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewModel by viewModels<UserListViewModel>()

        lifecycleScope.launch {
            viewModel.pagingFlow
                .collectLatest { pagingData ->
                    // submitData suspends until loading this generation of data stops
                    // so be sure to use collectLatest {} when presenting a Flow<PagingData>
                    pagingAdapter.submitData(pagingData)
                }
        }
    }
}

See Also

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.

import androidx.activity.viewModels
import androidx.lifecycle.observe

class MyLiveDataActivity : AppCompatActivity() {
    val pagingAdapter = UserPagingAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewModel by viewModels<UserListViewModel>()

        viewModel.pagingLiveData.observe(this) { pagingData ->
            pagingAdapter.submitData(lifecycle, pagingData)
        }
    }
}
import androidx.activity.viewModels

class MyRxJava2Activity : AppCompatActivity() {
    val pagingAdapter = UserPagingAdapter()
    val disposable = CompositeDisposable()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewModel by viewModels<UserListViewModel>()

        viewModel.pagingFlowable
            .autoDispose(this) // Using AutoDispose to handle subscription lifecycle
            .subscribe { pagingData ->
                pagingAdapter.submitData(lifecycle, pagingData)
            }
    }
}

See Also

withLoadStateFooter

fun withLoadStateFooter(footer: LoadStateAdapter<*>): ConcatAdapter

Create a ConcatAdapter with the provided LoadStateAdapters displaying the LoadType.PREPEND as a list item at the start of the presented list.

withLoadStateHeader

fun withLoadStateHeader(header: LoadStateAdapter<*>): ConcatAdapter

Create a ConcatAdapter with the provided LoadStateAdapters displaying the LoadType.APPEND as a list item at the end of the presented list.

withLoadStateHeaderAndFooter

fun withLoadStateHeaderAndFooter(
    header: LoadStateAdapter<*>,
    footer: LoadStateAdapter<*>
): ConcatAdapter

Create a ConcatAdapter with the provided LoadStateAdapters displaying the LoadType.PREPEND and LoadType.APPENDs as list items at the start and end respectively.

Protected methods

getItem

protected fun getItem(@IntRange(0) position: Int): T?

Returns the presented item at the specified position, notifying Paging of the item access to trigger any loads necessary to fulfill prefetchDistance.

Parameters
position: Int Index of the presented item to return, including placeholders.
Return
The presented item at position, null if it is a placeholder

Properties

dataRefreshFlow

val dataRefreshFlow: Flow<Boolean>

Deprecated.

A Flow of Boolean that is emitted when new PagingData generations are submitted and displayed. The Boolean that is emitted is true if the new PagingData is empty, false otherwise.

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 immediately delivers the current load states on collection.