如何在 ViewPager2 中使用 ItemTouchHelper.SimpleCallback?
How to use ItemTouchHelper.SimpleCallback with ViewPager2?
我使用 ViewPager2
创建了一个图像滑块,我需要一个功能,当我向上滑动时应该删除图像。我已经与 RecyclerView
合作过。所以我记得我可以使用 ItemTouchHelper.SimpleCallback
滑动来删除功能。但是 attachToRecyclerView
方法需要 RecyclerView
而不是 ViewPager2
即使 viewpager2
使用 RecyclerView 适配器。
科特林:
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)
默认情况下 ViewPager2
的 RecyclerView
不可访问,但您可以使用 reflection.
强制其可访问性
因为您需要通过使用 getDeclaredField()
, and for RecyclerView
it is: mRecyclerView (you can check it in the ViewPager2
class)
反映其声明的字段名称来访问 RecyclerView
然后使用 setAccessible()
使该字段可访问,以便允许将其用于 ItemTouchHelper
。
这里是 return 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
}
您可以像这样使用它:
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())
预览:
更新:
感谢 ,有一个很好的方法来获取 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)
}
这是从ViewPager2获取RecyclerView的另一种方法。我假设您有一个名为 PictureItemAdapter 的适配器:
class PictureItemAdapter(private val recyclerViewAttached: (RecyclerView) -> Unit) : RecyclerView.Adapter<PictureItemViewHolder>() {
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
recyclerViewAttached(recyclerView)
}
...
}
并且您将从 recyclerViewAttached
闭包中接收 Recycler 视图
val pictureItemAdapter = PictureItemAdapter{ recyclerView ->
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(recyclerView)
}
binding.viewPager.adapter = pictureItemAdapter
注意:RecyclerViewAdapter 和 FragmentStateAdapter 都有一个 onAttachedToRecyclerView 方法。
我使用 ViewPager2
创建了一个图像滑块,我需要一个功能,当我向上滑动时应该删除图像。我已经与 RecyclerView
合作过。所以我记得我可以使用 ItemTouchHelper.SimpleCallback
滑动来删除功能。但是 attachToRecyclerView
方法需要 RecyclerView
而不是 ViewPager2
即使 viewpager2
使用 RecyclerView 适配器。
科特林:
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)
默认情况下 ViewPager2
的 RecyclerView
不可访问,但您可以使用 reflection.
因为您需要通过使用 getDeclaredField()
, and for RecyclerView
it is: mRecyclerView (you can check it in the ViewPager2
class)
RecyclerView
然后使用 setAccessible()
使该字段可访问,以便允许将其用于 ItemTouchHelper
。
这里是 return 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
}
您可以像这样使用它:
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())
预览:
更新:
感谢 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)
}
这是从ViewPager2获取RecyclerView的另一种方法。我假设您有一个名为 PictureItemAdapter 的适配器:
class PictureItemAdapter(private val recyclerViewAttached: (RecyclerView) -> Unit) : RecyclerView.Adapter<PictureItemViewHolder>() {
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
recyclerViewAttached(recyclerView)
}
...
}
并且您将从 recyclerViewAttached
闭包中接收 Recycler 视图
val pictureItemAdapter = PictureItemAdapter{ recyclerView ->
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(recyclerView)
}
binding.viewPager.adapter = pictureItemAdapter
注意:RecyclerViewAdapter 和 FragmentStateAdapter 都有一个 onAttachedToRecyclerView 方法。