拖放以重新排序并从一个回收视图移动到另一个回收视图

发布于 2025-01-19 04:18:13 字数 3835 浏览 0 评论 0原文

我正在构建一个应用程序,以便能够将项目从一个回收视图拖动到另一个回收视图,并且我仍然必须保留在单个回收器视图内重新排序的选项。

因此,我已经定义了一个重新排序回调,

class ReorderHelperCallback(val adapter : ItemTouchHelperAdapter): ItemTouchHelper.Callback() {

    override fun getMovementFlags(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder
    ): Int {
        val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN or
                ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
        return makeMovementFlags( dragFlags, 0)//swipeFlags )
    }

    override fun onMove(
        recyclerView: RecyclerView,
        source: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        adapter.onItemMove(source.getAdapterPosition(),
            target.adapterPosition)
        return true
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        //Not use for Drag N Drop
    }

}

也是一个接口:

interface OnStartDragListener {
    fun onStartDrag(viewHolder: RecyclerView.ViewHolder?)
}

和一个 touchhelper:

interface ItemTouchHelperAdapter {
    fun onItemMove(fromPosition: Int, toPosition: Int): Boolean
    fun onItemDismiss(position: Int)
}

为了允许重新排序工作,我必须更新 Recycler 视图适配器,如下所示:


class Adapter(
    private var context: Context?,
    val dragStartListener : OnStartDragListener
): RecyclerView.Adapter<Adapter.ViewHolder>(), ItemTouchHelperAdapter {

    var arrayItems : ArrayList<Data?> = ArrayList()

    fun setData(array : MutableList<Data?>){
        array.toCollection(arrayItems)
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int {
        return arrayItems.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Adapter.ViewHolder {
        val binding = DashboardTileLayoutBinding
            .inflate(LayoutInflater.from(parent.context), parent, false)
        return ViewHolder(binding, dragStartListener)
    }

    override fun onBindViewHolder(holder: Adapter.ViewHolder, position: Int) {
        holder.setData(arrayItems[position])
    }

    inner class ViewHolder(val binding: LayoutBinding,
                           val dragStartListener : OnStartDragListener? = null)
        : RecyclerView.ViewHolder(binding.root) {

        val tileLayout = binding.tileLayout

        fun setData(data: Data?) {

           ....
            tileLayout.setOnDragListener { view, dragEvent ->
                when(dragEvent.action) {
                    ACTION_DRAG_STARTED -> {
                        dragStartListener?.onStartDrag(this)
                        true
                    }
                    else -> false
                }
            }
        }
    }

    override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
        Collections.swap(arrayItems, fromPosition, toPosition)
        notifyItemMoved(fromPosition, toPosition)
        return true
    }

    override fun onItemDismiss(position: Int) {
        TODO("Not yet implemented")
    }


}

以及包含 rv 的片段,我已经更新了适配器 init:

list1adapter?.let { adapter ->
                adapter.setData(list)
                val callback: ItemTouchHelper.Callback = ReorderHelperCallback(adapter)
                mItemTouchHelperSelected = ItemTouchHelper(callback)
                mItemTouchHelperSelected?.attachToRecyclerView(selectedLayout)
            }
---


override fun onStartDrag(viewHolder: RecyclerView.ViewHolder?) {
        viewHolder?.let {
            mItemTouchHelperSelected?.startDrag(it)
        }
    }

但是我的片段包含 2 个回收器视图。 list1 工作正常,用户可以通过拖放来重新排序该项目,但现在,我还希望能够将一个项目从我的 rv list1 移动到 list2,反之亦然。

有什么想法,如何使其成为 Kotlin 吗?我尝试了示例代码,但我失去了重新排序。

谢谢

I am building an app to be able to drag an item from one recycle view to another and I still have to keep the option to re-order inside a single recycler view.

So I have defined a Reorder Callback already

class ReorderHelperCallback(val adapter : ItemTouchHelperAdapter): ItemTouchHelper.Callback() {

    override fun getMovementFlags(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder
    ): Int {
        val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN or
                ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
        return makeMovementFlags( dragFlags, 0)//swipeFlags )
    }

    override fun onMove(
        recyclerView: RecyclerView,
        source: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        adapter.onItemMove(source.getAdapterPosition(),
            target.adapterPosition)
        return true
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        //Not use for Drag N Drop
    }

}

also an interface:

interface OnStartDragListener {
    fun onStartDrag(viewHolder: RecyclerView.ViewHolder?)
}

and a touchhelper:

interface ItemTouchHelperAdapter {
    fun onItemMove(fromPosition: Int, toPosition: Int): Boolean
    fun onItemDismiss(position: Int)
}

to allow the reorder to work, I had to update the Recycler view adapter as below:


class Adapter(
    private var context: Context?,
    val dragStartListener : OnStartDragListener
): RecyclerView.Adapter<Adapter.ViewHolder>(), ItemTouchHelperAdapter {

    var arrayItems : ArrayList<Data?> = ArrayList()

    fun setData(array : MutableList<Data?>){
        array.toCollection(arrayItems)
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int {
        return arrayItems.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Adapter.ViewHolder {
        val binding = DashboardTileLayoutBinding
            .inflate(LayoutInflater.from(parent.context), parent, false)
        return ViewHolder(binding, dragStartListener)
    }

    override fun onBindViewHolder(holder: Adapter.ViewHolder, position: Int) {
        holder.setData(arrayItems[position])
    }

    inner class ViewHolder(val binding: LayoutBinding,
                           val dragStartListener : OnStartDragListener? = null)
        : RecyclerView.ViewHolder(binding.root) {

        val tileLayout = binding.tileLayout

        fun setData(data: Data?) {

           ....
            tileLayout.setOnDragListener { view, dragEvent ->
                when(dragEvent.action) {
                    ACTION_DRAG_STARTED -> {
                        dragStartListener?.onStartDrag(this)
                        true
                    }
                    else -> false
                }
            }
        }
    }

    override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
        Collections.swap(arrayItems, fromPosition, toPosition)
        notifyItemMoved(fromPosition, toPosition)
        return true
    }

    override fun onItemDismiss(position: Int) {
        TODO("Not yet implemented")
    }


}

and the fragment which contain the rv, I have updated the adapter init:

list1adapter?.let { adapter ->
                adapter.setData(list)
                val callback: ItemTouchHelper.Callback = ReorderHelperCallback(adapter)
                mItemTouchHelperSelected = ItemTouchHelper(callback)
                mItemTouchHelperSelected?.attachToRecyclerView(selectedLayout)
            }
---


override fun onStartDrag(viewHolder: RecyclerView.ViewHolder?) {
        viewHolder?.let {
            mItemTouchHelperSelected?.startDrag(it)
        }
    }

But my fragment contain 2 recycler views. list1 is working fine to user drag and drop to re-order the item but now, I would like to also be able to move an item from my rv list1 to the list2 and vice versa

Any idea, how to make it Kotlin ? I tried an sample code, byt I am losing the re-ordering.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文