Android SortedList拖放订单项目并抛出IndexOutOfBoundsException:检测到不一致。无效的视图支架适配器positionViewHolde

问题描述 投票:0回答:1

我在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)
android kotlin android-recyclerview android-viewholder itemtouchhelper
1个回答
0
投票

不是使用updateItemAt,而是尝试使用notifyItemMoved(fromPosition, toPosition)提供的方法RecyclerView.Adapter

override fun onItemMove(fromPosition: Int, toPosition: Int) {
    notifyItemMoved(fromPosition, toPosition)
}
© www.soinside.com 2019 - 2024. All rights reserved.