我有一个回收器视图,它的列表存储在firestore中。我想允许用户使用拖放功能对项目重新排序。当用户删除保持(放下项目)时,我想调用该函数来更新 firestore,但是只要位置发生更改,即使拖动到所需位置,该函数也会被调用。如何仅在放置项目时调用该函数。
val itemTouchHelper = ItemTouchHelper(
object: ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0){
override fun onMove(
recyclerView: RecyclerView,
source: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
val sourcePosition = source.adapterPosition
val targetPosition = target.adapterPosition
Collections.swap(itemList, sourcePosition, targetPosition)
adapter.notifyItemMoved(sourcePosition, targetPosition)
// Firestore update
updateFirestoreList()
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
TODO("Not yet implemented")
}
})
当您选择拖动时,存储此位置
var sourcePosition = -1
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
super.onSelectedChanged(viewHolder, actionState)
if(actionState != ItemTouchHelper.ACTION_STATE_IDLE){
sourcePosition = viewHolder!!.adapterPosition
}
}
当你放下
clearView
时会被调用,获取ViewHolder的位置并交换Collection
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
super.clearView(recyclerView, viewHolder)
val targetPosition = viewHolder.adapterPosition
if(sourcePosition != -1 && sourcePosition != targetPosition){
Collections.swap(itemList, sourcePosition, targetPosition)
}
sourcePosition = -1
}
我希望它有帮助:))
我实现它的方法是重写
clearView()
的 ItemTouchHelper
方法,并从中调用回调。它会像下面这样:
class MyTouchHelper(val onActionEnded: () -> Unit) : ItemTouchHelper.SimpleCallback(UP or DOWN, 0) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder,
): Boolean {
recyclerView.adapter?.let { adapter ->
adapter as MyListAdapter
val from = viewHolder.absoluteAdapterPosition
val to = target.absoluteAdapterPosition
adapter.onItemMoved(from, to)
return true
}
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
super.clearView(recyclerView, viewHolder)
onActionEnded()
}
}
onItemMovied(from, to)
MyListAdapter
类中的一个函数,其实现如下:fun onItemMoved(from: Int, to: Int) {
val list = currentList.toMutableList()
list.add(to, list.removeAt(from))
submitList(list)
}
它只是用新项目的位置更新列表(您可能有不同的方法,请根据您的需要随意使用它或根本不使用它)。@viethoang更新列表本身的实现似乎更高效。我建议尝试一下。
最后,在附加
MyTouchHelper
的地方,您可以使用它的回调来调用您的特定函数,如下所示:
ItemTouchHelper(MyTouchHelper {
updateFirestoreList()// Or any other functions that you want.
}).attachToRecyclerView(recyclerView)
希望有帮助。
您可以使用这个
ItemMoveCallback
来实现这一点。
class ItemMoveCallback(var mAdapter: ItemTouchHelperContract) : ItemTouchHelper.Callback() {
override fun isLongPressDragEnabled(): Boolean {
return false
}
override fun isItemViewSwipeEnabled(): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) {}
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
return makeMovementFlags(dragFlags, ItemTouchHelper.ACTION_STATE_IDLE)
}
override fun onMove(
recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
mAdapter.onRowMoved(viewHolder.adapterPosition, target.adapterPosition)
return true
}
override fun onSelectedChanged(
viewHolder: RecyclerView.ViewHolder?,
actionState: Int
) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
if (viewHolder is RecyclerView.ViewHolder) {
val myViewHolder: RecyclerView.ViewHolder = viewHolder
mAdapter.onRowSelected(myViewHolder)
}
}
super.onSelectedChanged(viewHolder, actionState)
}
override fun clearView(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
) {
super.clearView(recyclerView, viewHolder)
val myViewHolder: RecyclerView.ViewHolder = viewHolder
mAdapter.onRowClear(myViewHolder)
}
interface ItemTouchHelperContract {
fun onRowMoved(fromPosition: Int, toPosition: Int)
fun onRowSelected(myViewHolder: RecyclerView.ViewHolder?)
fun onRowClear(myViewHolder: RecyclerView.ViewHolder?)
}
}
现在,在您的 recyclerview 适配器中,
class MYAdapter : RecyclerView.Adapter<VH>, ItemMoveCallback.ItemTouchHelperContract {
.........
.........
override fun onRowMoved(fromPosition: Int, toPosition: Int) {
if (fromPosition < toPosition) {
for (i in fromPosition until toPosition) {
Collections.swap(itemsList, i, i + 1)
}
} else {
for (i in fromPosition downTo toPosition + 1) {
Collections.swap(itemsList, i, i - 1)
}
}
notifyItemMoved(fromPosition, toPosition)
}
override fun onRowSelected(myViewHolder: RecyclerView.ViewHolder?) {
binding.root.setBackgroundColor(Color.GRAY)
// Apply the logic of notifying the user that item is selected here.
}
override fun onRowClear(myViewHolder: RecyclerView.ViewHolder?) {
binding.root.setBackgroundColor(Color.TRANSPARENT)
yourListenerToUpdateData?.onDataReordered(itemsList)
}
}