关于RecycleView 拖拽之后数据显示错乱的问题。

 ItemTouchHelper.Callback的监听

public class SimpleOnItemTouchCallBack extends ItemTouchHelper.Callback {

    private OnItemTouchHelpAdapter mAdapter;
    private int startPosition = -1;//记录按下时的Position

    public SimpleOnItemTouchCallBack(OnItemTouchHelpAdapter mAdapter) {
        this.mAdapter = mAdapter;
    }

    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);
        if(actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            mAdapter.onItemSelect(viewHolder);
        }
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP|ItemTouchHelper.DOWN;
        int swapFlags = ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
        return makeMovementFlags(dragFlags,swapFlags);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        if(startPosition<0)
        startPosition = viewHolder.getAdapterPosition();

        mAdapter.onItemMove(viewHolder,target);
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        mAdapter.onItemDelete(viewHolder);
    }

    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        if(viewHolder!=null) {
            mAdapter.onItemReset(viewHolder, startPosition);
            startPosition = -1;//拖拽完成之后还原
        }
    }
}
 

 

 

@Override
    public void onItemMove(RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
        int fromPosition = source.getAdapterPosition();
        int toPosition = target.getLayoutPosition();

        if (fromPosition < mDatas.size() && toPosition < mDatas.size()) {

//该方法是对数据直接的移动 例如mDatas[1,2,3,4,5,6,7,8] 执行itemMove(0,7)之后会变成2,3,4,5,6,7,8,1
            itemMove(fromPosition, toPosition);

//这个方法是实现对数据的交换,并不是移动数据

//例如mDatas[1,2,3,4,5,6,7,8] Collections.swap(mDatas,0,7);之后就会变成8,2,3,4,5,6,7,1
//            Collections.swap(mDatas,fromPosition,toPosition);

//执行交换的动画(注意:这里移动Item将position也一起移动了。例如:0元素移动到7的位置之后,点击7位置的元素之后打

//印position 发现它的position是0并不是7。
            notifyItemMoved(fromPosition, toPosition);
        }
    }

    private void itemMove(int fromPosition, int toPosition) {
        mDatas.add(toPosition, mDatas.remove(fromPosition));
    }

 

 

 @Override
    public void onItemReset(RecyclerView.ViewHolder source, int fromPosition) {
        source.itemView.setScaleX(1.0f);
        source.itemView.setScaleY(1.0f);

//该方法是移动结束后调用的。这里需要刷新一下数据将item刷新到正常状态

//这时点击移动后的item就会发现position也变了。例如:从0移动到7之后,该元素的position就不再是0而是7

        if (fromPosition >= 0) {
            int toPosition = source.getAdapterPosition();
            notifyItemRangeChanged(Math.min(fromPosition, toPosition), Math.abs(fromPosition - toPosition) + 1);
        }
    }

 

@Override
    public void onItemDelete(RecyclerView.ViewHolder source) {
        int position = source.getAdapterPosition();
        mDatas.remove(position);
        notifyItemRemoved(position);

  • //同理删除一个元素之后,后面的坐标都会变得,需要刷新后面所有的position

        notifyItemRangeChanged(source.getAdapterPosition(),mDatas.size()-source.getAdapterPosition());
    }

 

注意:刷新Item的position会出现闪动的动画

需要加上这句话:((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

 

你可能感兴趣的:(Android)