I have created a image slider using ViewPager2
, I need a functionality that when I swipe up the image should be removed. I already worked with RecyclerView
. So I remember I can use ItemTouchHelper.SimpleCallback
for swipe to remove functionality. But attachToRecyclerView
method requires a RecyclerView
not a ViewPager2
even though viewpager2
uses RecyclerView adapter.
Kotlin:
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)
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)
}