如何在 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)

默认情况下 ViewPager2RecyclerView 不可访问,但您可以使用 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

注意:RecyclerViewAdapterFragmentStateAdapter 都有一个 onAttachedToRecyclerView 方法。