LoadStateAdapter
abstract class LoadStateAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>
Adapter for displaying a RecyclerView item based on LoadState, such as a loading spinner, or
a retry error button.
By default will use one shared view type for all
items.
By default, both LoadState.Loading and LoadState.Error are presented as adapter items,
other states are not. To configure this, override displayLoadStateAsItem.
To present this Adapter as a header and or footer alongside your PagingDataAdapter, see
PagingDataAdapter.withLoadStateHeaderAndFooter, or use
ConcatAdapter directly to concatenate Adapters.
class LoadStateViewHolder(
parent: ViewGroup,
retry: () -> Unit
) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.load_state_item, parent, false)
) {
private val progressBar: ProgressBar = itemView.findViewById(R.id.progress_bar)
private val errorMsg: TextView = itemView.findViewById(R.id.error_msg)
private val retry: Button = itemView.findViewById<Button>(R.id.retry_button)
.also { it.setOnClickListener { retry.invoke() } }
fun bind(loadState: LoadState) {
if (loadState is LoadState.Error) {
errorMsg.text = loadState.error.localizedMessage
}
progressBar.visibility = toVisibility(loadState is LoadState.Loading)
retry.visibility = toVisibility(loadState !is LoadState.Loading)
errorMsg.visibility = toVisibility(loadState !is LoadState.Loading)
}
private fun toVisibility(constraint: Boolean): Int = if (constraint) {
View.VISIBLE
} else {
View.GONE
}
}
/**
* Adapter which displays a loading spinner when `state = LoadState.Loading`, and an error
* message and retry button when `state is LoadState.Error`.
*/
class MyLoadStateAdapter(
private val retry: () -> Unit
) : LoadStateAdapter<LoadStateViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState) =
LoadStateViewHolder(parent, retry)
override fun onBindViewHolder(holder: LoadStateViewHolder, loadState: LoadState) =
holder.bind(loadState)
}
Summary
Public constructors |
Adapter for displaying a RecyclerView item based on LoadState, such as a loading spinner, or
a retry error button.
|
Public methods |
open Boolean |
Returns true if the LoadState should be displayed as a list item when active.
|
Int |
|
Int |
|
open Int |
Override this method to use different view types per LoadState.
|
Unit |
|
abstract Unit |
Called to bind the passed LoadState to the ViewHolder.
|
VH |
|
abstract VH |
Called to create a ViewHolder for the given LoadState.
|
Inherited functions |
From class Adapter
Unit |
bindViewHolder(@NonNull holder: VH, position: Int)
This method internally calls onBindViewHolder(ViewHolder, int) to update the ViewHolder contents with the item at the given position and also sets up some private fields to be used by RecyclerView. Adapters that merge other adapters should use bindViewHolder(ViewHolder, int) when calling nested adapters so that RecyclerView can track which adapter bound the ViewHolder to return the correct position from ViewHolder#getBindingAdapterPosition() method. They should also override the findRelativeAdapterPositionIn(Adapter, ViewHolder, int) method.
|
VH |
createViewHolder(@NonNull parent: ViewGroup, viewType: Int)
This method calls onCreateViewHolder(ViewGroup, int) to create a new ViewHolder and initializes some private fields to be used by RecyclerView.
|
Int |
findRelativeAdapterPositionIn(@NonNull adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder!>, @NonNull viewHolder: RecyclerView.ViewHolder, localPosition: Int)
Returns the position of the given ViewHolder in the given Adapter . If the given Adapter is not part of this Adapter , RecyclerView#NO_POSITION is returned.
|
Long |
getItemId(position: Int)
Return the stable ID for the item at position . If hasStableIds() would return false this method should return NO_ID . The default implementation of this method returns NO_ID .
|
RecyclerView.Adapter.StateRestorationPolicy |
getStateRestorationPolicy()
Returns when this Adapter wants to restore the state.
|
Boolean |
hasObservers()
Returns true if one or more observers are attached to this adapter.
|
Boolean |
hasStableIds()
Returns true if this adapter publishes a unique long value that can act as a key for the item at a given position in the data set. If that item is relocated in the data set, the ID returned for that item should be the same.
|
Unit |
notifyDataSetChanged()
Notify any registered observers that the data set has changed.
There are two different classes of data change events, item changes and structural changes. Item changes are when a single item has its data updated but no positional changes have occurred. Structural changes are when items are inserted, removed or moved within the data set.
This event does not specify what about the data set has changed, forcing any observers to assume that all existing items and structure may no longer be valid. LayoutManagers will be forced to fully rebind and relayout all visible views.
RecyclerView will attempt to synthesize visible structural change events for adapters that report that they have stable IDs when this method is used. This can help for the purposes of animation and visual object persistence but individual item views will still need to be rebound and relaid out.
If you are writing an adapter it will always be more efficient to use the more specific change events if you can. Rely on notifyDataSetChanged() as a last resort.
|
Unit |
notifyItemChanged(position: Int)
Notify any registered observers that the item at position has changed. Equivalent to calling notifyItemChanged(position, null); .
This is an item change event, not a structural change event. It indicates that any reflection of the data at position is out of date and should be updated. The item at position retains the same identity.
|
Unit |
notifyItemChanged(position: Int, @Nullable payload: Any?)
Notify any registered observers that the item at position has changed with an optional payload object.
This is an item change event, not a structural change event. It indicates that any reflection of the data at position is out of date and should be updated. The item at position retains the same identity.
Client can optionally pass a payload for partial change. These payloads will be merged and may be passed to adapter's onBindViewHolder(ViewHolder, int, List) if the item is already represented by a ViewHolder and it will be rebound to the same ViewHolder. A notifyItemRangeChanged() with null payload will clear all existing payloads on that item and prevent future payload until onBindViewHolder(ViewHolder, int, List) is called. Adapter should not assume that the payload will always be passed to onBindViewHolder(), e.g. when the view is not attached, the payload will be simply dropped.
|
Unit |
notifyItemInserted(position: Int)
Notify any registered observers that the item reflected at position has been newly inserted. The item previously at position is now at position position + 1 .
This is a structural change event. Representations of other existing items in the data set are still considered up to date and will not be rebound, though their positions may be altered.
|
Unit |
notifyItemMoved(fromPosition: Int, toPosition: Int)
Notify any registered observers that the item reflected at fromPosition has been moved to toPosition .
This is a structural change event. Representations of other existing items in the data set are still considered up to date and will not be rebound, though their positions may be altered.
|
Unit |
notifyItemRangeChanged(positionStart: Int, itemCount: Int)
Notify any registered observers that the itemCount items starting at position positionStart have changed. Equivalent to calling notifyItemRangeChanged(position, itemCount, null); .
This is an item change event, not a structural change event. It indicates that any reflection of the data in the given position range is out of date and should be updated. The items in the given range retain the same identity.
|
Unit |
notifyItemRangeChanged(positionStart: Int, itemCount: Int, @Nullable payload: Any?)
Notify any registered observers that the itemCount items starting at position positionStart have changed. An optional payload can be passed to each changed item.
This is an item change event, not a structural change event. It indicates that any reflection of the data in the given position range is out of date and should be updated. The items in the given range retain the same identity.
Client can optionally pass a payload for partial change. These payloads will be merged and may be passed to adapter's onBindViewHolder(ViewHolder, int, List) if the item is already represented by a ViewHolder and it will be rebound to the same ViewHolder. A notifyItemRangeChanged() with null payload will clear all existing payloads on that item and prevent future payload until onBindViewHolder(ViewHolder, int, List) is called. Adapter should not assume that the payload will always be passed to onBindViewHolder(), e.g. when the view is not attached, the payload will be simply dropped.
|
Unit |
notifyItemRangeInserted(positionStart: Int, itemCount: Int)
Notify any registered observers that the currently reflected itemCount items starting at positionStart have been newly inserted. The items previously located at positionStart and beyond can now be found starting at position positionStart + itemCount .
This is a structural change event. Representations of other existing items in the data set are still considered up to date and will not be rebound, though their positions may be altered.
|
Unit |
notifyItemRangeRemoved(positionStart: Int, itemCount: Int)
Notify any registered observers that the itemCount items previously located at positionStart have been removed from the data set. The items previously located at and after positionStart + itemCount may now be found at oldPosition - itemCount .
This is a structural change event. Representations of other existing items in the data set are still considered up to date and will not be rebound, though their positions may be altered.
|
Unit |
notifyItemRemoved(position: Int)
| |