AdapterDelegates
AdapterDelegates copied to clipboard
Jetpack Paging 3 support
Hi,
Paging 3 is a complete rework of previous paging solution by Google. Adapter delegates have support for version 2.
Would be good to have support for version 3 as well. Though version 3 is just announced and is currently in alpha, still would be good to have some initial support.
https://developer.android.com/topic/libraries/architecture/paging/v3-overview
Thank you
I've tried to make an adapter, similar to what there is for v2 paging. But faced an issue that I couldn't find a way to extract "currentList" data from the PagingDataAdapter (or it's differ). Seems like paging lib goes directly into "1 view type" per whole adapter (with separate implementation for header and footer) and doesn't expose list directly.
So, workarounded that in the following way:
class PagingDataDelegationAdapter<T : Any>(
diffCallback: DiffUtil.ItemCallback<T>,
vararg delegates: AdapterDelegate<List<T>>
) : PagingDataAdapter<T, RecyclerView.ViewHolder>(diffCallback) {
private val delegatesManager: AdapterDelegatesManager<List<T>> = AdapterDelegatesManager()
init {
delegates.forEach { delegatesManager.addDelegate(it) }
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return delegatesManager.onCreateViewHolder(parent, viewType)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
//// here directly taking item and passing it to onBindViewHolder (wrapping into list to conform the adapterdelegates API)
val item =
getItem(position) // Internally triggers loading items around items around the given position
val delegate = delegatesManager.getDelegateForViewType(holder.itemViewType)
?: throw NullPointerException(
"No delegate found for item at position = "
+ position
+ " for viewType = "
+ holder.itemViewType
)
delegate.onBindViewHolder(listOf(item as T), 0, holder, emptyList())
}
override fun getItemViewType(position: Int): Int {
///// here just return whatever as multiple view types are not supported
return 0
}
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
delegatesManager.onViewRecycled(holder)
}
override fun onFailedToRecycleView(holder: RecyclerView.ViewHolder): Boolean {
return delegatesManager.onFailedToRecycleView(holder)
}
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
delegatesManager.onViewAttachedToWindow(holder)
}
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
delegatesManager.onViewDetachedFromWindow(holder)
}
}
Could be good if someone also took a look at that. Maybe there is something that needs to be updated in the API of adapterdelegates, or maybe something can be incorporated as a feedback to Jetpack team (so they might expose "currentList" or something similar in the public api)
Thank you
Do you want to send me a PR for this?
Hi @sockeqwe
I'd be happy to help with that, but I have a feeling that it would be not that easy. What I've posted above is definitely a hack and I don't think it should be added like this into lib.
Main issue I see is in AdapterDelegate interface. It is low-level interface in the whole lib, and it defines everything in terms of adapter's underlying list and position.
public abstract class AdapterDelegate<T> {
protected abstract boolean isForViewType(@NonNull T items, int position);
protected abstract void onBindViewHolder(@NonNull T items, int position,
@NonNull RecyclerView.ViewHolder holder, @NonNull List<Object> payloads);
Here items
are meant as "datasource". Though all of the implementations in library seem to rely on List to be a datasource.
In Paging 3 lists are not exposed and not used inside. There are NullPaddedLists, but it is separate interface which doesn't relate to general List interface.
Instead there are methods to get itemCount and item by position. It is technically possible to create some Provider interface and base solution on AdapterDelegate<Provider<T>>. But this would require to create whole new branch of the classes (including bindings etc)
Another workaround would be to make method "getCurrentList" as in Paging2 adapter based on getItem(position) and getItemCount. But that would have bad performance I guess.
So, I'd be happy to help, but atm I'm a bit stuck on what is the right direction.
Hello! @sockeqwe Do you have plans to support the paging 3 officially in the nearest future?
Hello, @sockeqwe I would be very happy if Paging 3 support becomes available in the near future.