Android SortedList 拖动并重新排序项目抛出 IndexOutOfBounds异常:检测到不一致.无效的



我遇到了使用sortedList实现回收器视图的问题.我需要为此回收视图实现拖动和重新排序功能,我使用了" ItemTouchHelper.Callback(("来处理向上/向下移动

class SimpleItemTouchHelperCallback(private val mAdapter: ItemTouchHelperAdapter) :
ItemTouchHelper.Callback() {
override fun onMove(
recyclerView: RecyclerView,
source: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
if (source.itemViewType != target.itemViewType) {
return false
}
val fromPosition = source.adapterPosition
val toPosition = target.adapterPosition
dragFrom = fromPosition
dragTo = toPosition
Timber.d(">> SimpleItemTouchHelperCallback ->>> onMove fromPosition = $fromPosition | toPosition = $toPosition")
// Notify the adapter of the move
mAdapter.onItemMove(dragFrom, dragTo)
return true
}

override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
super.clearView(recyclerView, viewHolder)
viewHolder.itemView.alpha = ALPHA_FULL
if (viewHolder is ItemTouchHelperViewHolder) {
// Tell the view holder it's time to restore the idle state
val itemViewHolder = viewHolder as ItemTouchHelperViewHolder
itemViewHolder.onItemClear()
// To detect when an interaction with an element is over
if (dragFrom != -1 && dragTo != -1 && dragFrom != dragTo) {
mAdapter.dragAndDropCompleted(dragFrom, dragTo)
}
dragFrom = -1
dragTo = -1
}
}
}
//===========
class ShoppingListRecyclerListAdapter(
private val onItemClickListener: OnItemClickListener,
private val userCheckedInToStore: Boolean
) : RecyclerView.Adapter<BaseShoppingListViewHolder>(), ItemTouchHelperAdapter {
private var sortedItemList: SortedList<ShoppingListEntry>
override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
var dragFromItem = sortedItemList[fromPosition]
var dragToItem = sortedItemList[toPosition]
if (dragFromItem is UnCheckedFreeTextItem && dragToItem is UnCheckedFreeTextItem) {

val dragFromItemSortIndex = dragFromItem.freeTextShoppingItem.sortIndex
val dragFromItemName = dragFromItem.freeTextShoppingItem.itemName

dragFromItem.freeTextShoppingItem.sortIndex =
dragToItem.freeTextShoppingItem.sortIndex
dragToItem.freeTextShoppingItem.sortIndex = dragFromItemSortIndex
dragToItem.modify = true
dragFromItem.modify = true

dragFromItem.freeTextShoppingItem.itemName =
dragToItem.freeTextShoppingItem.itemName
dragToItem.freeTextShoppingItem.itemName = dragFromItemName

dragItemSet.add(dragToItem)
dragItemSet.add(dragFromItem)
sortedItemList.beginBatchedUpdates()
//sortedItemList.recalculatePositionOfItemAt(fromPosition)
sortedItemList.updateItemAt(fromPosition, dragFromItem)
//sortedItemList.recalculatePositionOfItemAt(toPosition)
sortedItemList.updateItemAt(toPosition, dragToItem)
//sortedItemList.recalculatePositionOfItemAt(fromPosition)
//sortedItemList.recalculatePositionOfItemAt(toPosition)
//sortedItemList.updateItemAt(fromPosition, dragToItem)
sortedItemList.endBatchedUpdates()
}

}
}

当用户长按项目并开始移动时出现异常

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{c026f4 position=6 id=39, oldPos=6, pLpos:-1 scrap [attachedScrap] 
tmpDetached no parent} androidx.recyclerview.widget.RecyclerView{1991c2a VFED.V... ......ID 0,364-1080,1980 #7f0a01db app:id/shoppingListView}, 
adapter:com.adingk.lib.ui.shoppinglist.ShoppingListRecyclerListAdapter@741fa1b, layout:androidx.recyclerview.widget.LinearLayoutManager@d2de7b8, 
context:com.adingk.lib.ui.shoppinglist.ManageShoppingListActivity@76ea334
at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5715)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5898)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3875)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3639)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4194)
at android.view.View.layout(View.java:21927)
at android.view.ViewGroup.layout(ViewGroup.java:6260)

与其使用updateItemAt不如尝试使用notifyItemMoved(fromPosition, toPosition)这是RecyclerView.Adapter提供的方法。

override fun onItemMove(fromPosition: Int, toPosition: Int) {
notifyItemMoved(fromPosition, toPosition)
}

相关内容

  • 没有找到相关文章

最新更新