The RecyclerView
of the ViewPager2
is not accessible by default, but you can enforce its accessibility using reflection.
In that you need to access the RecyclerView
by reflecting its declared field name using getDeclaredField()
, and for RecyclerView
it is: mRecyclerView (you can check it in the ViewPager2
class)
Then use setAccessible()
to make this field accessible in order to allow using it for the ItemTouchHelper
.
Here is an extension function to return the ViewPager2
ReyclerView
:
fun ViewPager2.getRecyclerView(): RecyclerView? {
try {
val field = ViewPager2::class.java.getDeclaredField("mRecyclerView")
field.isAccessible = true
return field.get(this) as RecyclerView
} catch (e: NoSuchFieldException) {
e.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
}
return null
}
And you can use it like:
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.UP) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
}
}).attachToRecyclerView(binding.viewPager.getRecyclerView())
Preview:

UPDATE:
Thanks to @SimpleAndroid answer, there is a nice way for obtaining the RecyclerView
:
viewPager.children.find { it is RecyclerView }?.let {
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.UP) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
}
}).attachToRecyclerView(it as RecyclerView)
}