首页 > 解决方案 > Android - 在 ConcatAdapter 上拖放

问题描述

我试图在 ConcatAdapter 中实现拖放。我做了一个 ConcatAdapter bc 我有多个项目不同的部分,所以我只需要在一个部分内拖放。

我做了一个带有 2 个适配器的 ConcatAdapter 我为回收器视图做了 ItemTouchHelper ->itemTouchHelper.attachToRecyclerView(binding.recyclerView)

我猜这与 ItemTouchHelper bc 相关,它设置在回收站视图上而不是适配器上。

有什么方法可以只为 ConcatAdapter 中的 1 个适配器设置拖放?

标签: android

解决方案


在 ItemTouchHelper.Callback 的 onMove 中,您可以决定忽略一些动作。使用 viewHolder(被拖动的 ViewHolder)和 targetViewHolder 并检查它们的 bindingAdapter。或者,如果它们是同一个适配器的实例,您可以使用在适配器初始化时设置的字段来确定它们是哪个适配器。

在下面的示例中,我有两个适配器,都是 TaskAdapter 类型,但第二个包含已完成的任务。未完成的任务不能在已完成的任务之间移动,已完成的任务根本不能移动。因此,如果 targetViewHolder 被标记为已完成的适配器绑定,我只返回 false 并忽略移动。显然,一个项目已被拖到该目标项目上,但由于它实际上并没有移动,因此用户理解这是不允许的并会放弃。我认为这比拥有多个 RecyclerViews 是可以接受的并且更好。

override fun onMove(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder,
    targetViewHolder: RecyclerView.ViewHolder
): Boolean {
    val targetAdapter = targetViewHolder.bindingAdapter as TaskAdapter
    if (targetAdapter.completed) return false
    val adapter = viewHolder.bindingAdapter as TaskAdapter
    adapter.moveItem(
        viewHolder.bindingAdapterPosition,
        targetViewHolder.bindingAdapterPosition
    )
    return true
}

如果你想让某些项目一开始就不能被拖动,你可以从 getDragDirs 返回 0。在此示例中,它们是已完成的任务。

override fun getDragDirs(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder
): Int {
    val adapter = viewHolder.bindingAdapter as TaskAdapter
    if (adapter.completed) return 0
    return super.getDragDirs(recyclerView, viewHolder)
}

推荐阅读