Android RecyclerView在嵌套的RecyclerView中第二次拖动项目时无法正常工作。

huangapple go评论73阅读模式
英文:

Android Recycleview dragging items within a nested recyclerview for the second time is not working properly

问题

I attempted to integrate the dragging feature for both the primary item and the extended list within that list.

It functioned OK, however when I closed and reopened an item, the item (in extended list) stopped moving with the cursor.

Check out this video to understand the issue.
video link

Adapter code.

class ItemAdapter(private val items: MutableList<ItemModel>) :
    RecyclerView.Adapter<ItemAdapter.ViewHolder>() {

    // Rest of your code...
}

If you identify any errors in my code, please let me know and give a solution. Thx!

英文:

I attempted to integrate the dragging feature for both the primary item and the extended list within that list.

It functioned OK, however when I closed and reopened an item, the item (in extended list) stopped moving with the cursor.

Check out this video to understand the issue.
video link

Adapter code.

class ItemAdapter(private val items: MutableList<ItemModel>) :
RecyclerView.Adapter<ItemAdapter.ViewHolder>() {

private var expandedItemPosition: Int = -1

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val binding: ItemListBinding =
        DataBindingUtil.inflate(inflater, R.layout.item_list, parent, false)
    return ViewHolder(binding)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.bind(items[position])
}

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

fun onItemMove(fromPosition: Int, toPosition: Int) {
    if (fromPosition < toPosition) {
        for (i in fromPosition until toPosition) {
            items[i] = items.set(i + 1, items[i])
        }
    } else {
        for (i in fromPosition downTo toPosition + 1) {
            items[i] = items.set(i - 1, items[i])
        }
    }
    notifyItemMoved(fromPosition, toPosition)
}

inner class ViewHolder(private val binding: ItemListBinding) :
    RecyclerView.ViewHolder(binding.root) {

    init {
        binding.root.setOnClickListener {
            val position = adapterPosition
            expandedItemPosition = if (position == expandedItemPosition) {
                -1 // Collapse the currently expanded item
            } else {
                position // Expand the clicked item
            }
            notifyDataSetChanged() // Notify the adapter of the item changes
        }
    }

    fun bind(item: ItemModel) {
        binding.viewModel = item
        val isExpanded = adapterPosition == expandedItemPosition
        binding.isExpanded = isExpanded
        binding.executePendingBindings()

        if (isExpanded) {
            val expandedRecyclerView = binding.expandedRecyclerView
            expandedRecyclerView.adapter = ExpandedItemAdapter(item.expandedList)

            val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
                ItemTouchHelper.UP or ItemTouchHelper.DOWN,
                0
            ) {
                override fun onMove(
                    recyclerView: RecyclerView,
                    viewHolder: RecyclerView.ViewHolder,
                    target: RecyclerView.ViewHolder
                ): Boolean {
                    val fromPosition = viewHolder.adapterPosition
                    val toPosition = target.adapterPosition
                    (expandedRecyclerView.adapter as ExpandedItemAdapter).onItemMove(
                        fromPosition,
                        toPosition
                    )
                    return true
                }

                override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                    Log.d("CheckingSwiped", "onSwiped: $adapterPosition")
                }

                override fun onMoved(
                    recyclerView: RecyclerView,
                    viewHolder: RecyclerView.ViewHolder,
                    fromPos: Int,
                    target: RecyclerView.ViewHolder,
                    toPos: Int,
                    x: Int,
                    y: Int
                ) {
                    Log.d("CheckingSwiped", "onMoved: $fromPos ::: $toPos")

                    super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
                }

                override fun isLongPressDragEnabled(): Boolean {
                    return true
                }
            })

            itemTouchHelper.attachToRecyclerView(expandedRecyclerView)
        } else {
            binding.expandedRecyclerView.adapter = null
        }
    }
}

}

If you identify any errors in my code, please let me know and give a solution. Thx!

答案1

得分: 1

以下是代码的翻译部分:

class ItemAdapter(private val items: MutableList<ItemModel>) :
    RecyclerView.Adapter<ItemAdapter.ViewHolder>() {

    private var expandedItemPosition: Int = -1
    private var itemTouchHelper: ItemTouchHelper? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val binding: ItemListBinding =
            DataBindingUtil.inflate(inflater, R.layout.item_list, parent, false)
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(items[position])
    }

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

    fun onItemMove(fromPosition: Int, toPosition: Int) {
        if (fromPosition < toPosition) {
            for (i in fromPosition until toPosition) {
                items[i] = items.set(i + 1, items[i])
            }
        } else {
            for (i in fromPosition downTo toPosition + 1) {
                items[i] = items.set(i - 1, items[i])
            }
        }
        notifyItemMoved(fromPosition, toPosition)
    }

    inner class ViewHolder(private val binding: ItemListBinding) :
        RecyclerView.ViewHolder(binding.root) {

        init {
            binding.root.setOnClickListener {
                val position = adapterPosition
                expandedItemPosition = if (position == expandedItemPosition) {
                    -1 // 收起当前展开的项目
                } else {
                    position // 展开被点击的项目
                }
                notifyDataSetChanged() // 通知适配器项目变化
            }
        }

        fun bind(item: ItemModel) {
            binding.viewModel = item
            val isExpanded = adapterPosition == expandedItemPosition
            binding.isExpanded = isExpanded
            binding.executePendingBindings()

            val expandedRecyclerView = binding.expandedRecyclerView
            if (isExpanded) {
                expandedRecyclerView.adapter = ExpandedItemAdapter(item.expandedList)
            } else {
                expandedRecyclerView.adapter = null
            }

            if (itemTouchHelper == null) {
                itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
                    ItemTouchHelper.UP or ItemTouchHelper.DOWN,
                    0
                ) {
                    override fun onMove(
                        recyclerView: RecyclerView,
                        viewHolder: RecyclerView.ViewHolder,
                        target: RecyclerView.ViewHolder
                    ): Boolean {
                        val fromPosition = viewHolder.adapterPosition
                        val toPosition = target.adapterPosition
                        (expandedRecyclerView.adapter as? ExpandedItemAdapter)?.onItemMove(
                            fromPosition,
                            toPosition
                        )
                        return true
                    }

                    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                        Log.d("CheckingSwiped", "onSwiped: $adapterPosition")
                    }

                    override fun onMoved(
                        recyclerView: RecyclerView,
                        viewHolder: RecyclerView.ViewHolder,
                        fromPos: Int,
                        target: RecyclerView.ViewHolder,
                        toPos: Int,
                        x: Int,
                        y: Int
                    ) {
                        Log.d("CheckingSwiped", "onMoved: $fromPos ::: $toPos")

                        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
                    }

                    override fun isLongPressDragEnabled(): Boolean {
                        return true
                    }
                })
                itemTouchHelper.attachToRecyclerView(expandedRecyclerView)
            } else {
                binding.expandedRecyclerView.adapter = null
            }
        }
    }
}
英文:

Check the below code may be it helpful

class ItemAdapter(private val items: MutableList&lt;ItemModel&gt;) :
RecyclerView.Adapter&lt;ItemAdapter.ViewHolder&gt;() {
private var expandedItemPosition: Int = -1
private var itemTouchHelper: ItemTouchHelper? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding: ItemListBinding =
DataBindingUtil.inflate(inflater, R.layout.item_list, parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
}
override fun getItemCount(): Int {
return items.size
}
fun onItemMove(fromPosition: Int, toPosition: Int) {
if (fromPosition &lt; toPosition) {
for (i in fromPosition until toPosition) {
items[i] = items.set(i + 1, items[i])
}
} else {
for (i in fromPosition downTo toPosition + 1) {
items[i] = items.set(i - 1, items[i])
}
}
notifyItemMoved(fromPosition, toPosition)
}
inner class ViewHolder(private val binding: ItemListBinding) :
RecyclerView.ViewHolder(binding.root) {
init {
binding.root.setOnClickListener {
val position = adapterPosition
expandedItemPosition = if (position == expandedItemPosition) {
-1 // Collapse the currently expanded item
} else {
position // Expand the clicked item
}
notifyDataSetChanged() // Notify the adapter of the item changes
}
}
fun bind(item: ItemModel) {
binding.viewModel = item
val isExpanded = adapterPosition == expandedItemPosition
binding.isExpanded = isExpanded
binding.executePendingBindings()
val expandedRecyclerView = binding.expandedRecyclerView
if (isExpanded) {
expandedRecyclerView.adapter = ExpandedItemAdapter(item.expandedList)
} else {
expandedRecyclerView.adapter = null
}
if (itemTouchHelper == null) {
itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
0
) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
val fromPosition = viewHolder.adapterPosition
val toPosition = target.adapterPosition
(expandedRecyclerView.adapter as? ExpandedItemAdapter)?.onItemMove(
fromPosition,
toPosition
)
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
Log.d(&quot;CheckingSwiped&quot;, &quot;onSwiped: $adapterPosition&quot;)
}
override fun onMoved(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
fromPos: Int,
target: RecyclerView.ViewHolder,
toPos: Int,
x: Int,
y: Int
) {
Log.d(&quot;CheckingSwiped&quot;, &quot;onMoved: $fromPos ::: $toPos&quot;)
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
}
override fun isLongPressDragEnabled(): Boolean {
return true
}
})
itemTouchHelper.attachToRecyclerView(expandedRecyclerView)
} else {
binding.expandedRecyclerView.adapter = null
}
}
}
}

huangapple
  • 本文由 发表于 2023年7月6日 17:27:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76627384.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定