TL;DR:
You can use
(viewPager2.getChildAt(0) as RecyclerView)
to access the internal RecyclerView
used inside the ViewPager2
for now, and you can call findViewHolderForAdapterPosition()
or findViewHolderForItemId()
as usual.
Explanation:
I had a custom view implementing a ViewPager
which could, in some cases, modify the inner views without having to recompute all of them for a small change.
This is not possible to do as such anymore, as the internal implementation is a bit different. As you know, ViewPager2
now uses a RecyclerView.Adapter
to handle the paged views, but how is it used internally?
Internals:
If we look at the children of an initialized ViewPager2
, we can see there is only one, a RecyclerViewImpl
. RecyclerViewImpl
is a new internal class used to manage the ViewPager2
internally, bringing a lot of benefits that ReyclerView
s have to ViewPager
. Unfortunately, this class is private and therefore inaccessible outside of ViewPager2
. So we're stuck?
Nope! RecyclerViewImpl
inherits from RecyclerView
, and it should be enough in most cases, and thankfully in ours, to use.
Solution:
So then we can use:
(viewPager2.getChildAt(0) as RecyclerView)
to access the internal RecyclerView
.
We can quickly wrap that in a Kotlin extension function to hide the complexity and simplify the use:
fun ViewPager2.findViewHolderForAdapterPosition(position: Int): RecyclerView.ViewHolder? {
return (getChildAt(0) as RecyclerView).findViewHolderForAdapterPosition(position)
}
You can adapt to something that suits your needs better of course, like for example directly returning the ViewHolder.itemView
.
⚠️ Warning : This relies on internal implementation, which could change at any time without warning. For now this is the only way that I found to access the underlying views, but a feature request is open here.
Top comments (0)