RecyclerView实现拖动效果,并解决里面的坑。

RecyclerView实现拖动效果,并解决里面的坑。

先上效果在这里插入图片描述

创建SimpleItemTouchHelper

public class SimpleItemTouchHelper extends ItemTouchHelper.Callback {
    private Activity activity;
    private OnMoveAndSwipedListener mAdapter;
    public final float ALPHA_FULL = 1.0f;

    public SimpleItemTouchHelper(Activity activity, OnMoveAndSwipedListener listener) {
        this.activity = activity;
        this.mAdapter = listener;
    }

    /**
     * 是否可以拖动
     *
     * @return
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    /**
     * 是否可以滑动
     *
     * @return
     */
    @Override
    public boolean isItemViewSwipeEnabled() {
        return false;
    }

    /**
     * 拖动的方向以及侧滑的方向
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //设置拖拽方向为上下
        final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        //设置侧滑方向 start从右到往左 end从左往右
        final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    /**
     * 拖动item时回调
     */
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        //当拖拽的item拖拽到另一种item上时不允许拖拽
        if (viewHolder.getItemViewType() != target.getItemViewType()) {
            return false;
        }
        //回调adapter中的onItemMove方法
        mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    /**
     * 拖动时会回调.在这里可以绘制item
     */
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            // Fade out the view as it is swiped out of the parent's bounds
            final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
            viewHolder.itemView.setAlpha(alpha);
            viewHolder.itemView.setTranslationX(dX);
        } else {
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
    }

    /**
     * 侧滑item后会回调
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
    }
}

OnMoveAndSwipedListener接口回调

public interface OnMoveAndSwipedListener {
    boolean onItemMove(int fromPosition, int toPosition);
    void onItemDismiss(int position);
}

在你的Adapter中实现 OnMoveAndSwipedListener接口

public boolean onItemMove(int fromPosition, int toPosition) {
        if (fromPosition < toPosition) {
            //从上往下拖动,每滑动一个item,都将list中的item向下交换,向上滑同理。
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(mList, i, i + 1);//交换数据源两个数据的位置
            }
        } else if(fromPosition > toPosition){
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(mList, i, i - 1);//交换数据源两个数据的位置
            }
        }
        //刷新列表数据
        notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    @Override
    public void onItemDismiss(int position) {

    }

在这里我没有实现侧滑删除,分享一个这里遇到的问题

重点在这里

因为onItemMove中的 notifyItemMoved(fromPosition, toPosition);会把索引值一块移动,下次再取值时,就会出现错乱现象,下面是我处理的方案。
在这里插入图片描述
在这里加入notifyItemRangeChanged(Math.min(fromPosition, toPosition), Math.abs(fromPosition - toPosition) +1);会将改动的position刷新一遍,从而再次取值时,不会再出现错乱现象。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现两个RecyclerView之间的item互相拖拽可以通过以下步骤进行: 1. 首先,在布局文件中分别添加两个RecyclerView控件。给它们分别设置不同的ID,方便后续代码操作。 2. 在代码中分别找到两个RecyclerView实例,并为它们设置LayoutManager和Adapter。确保两个RecyclerView显示的数据不同。 3. 为每个RecyclerView的Item添加拖拽功能,可以使用ItemTouchHelper类来实现。创建一个ItemTouchHelper实例,并将其附加到两个RecyclerView上。 4. 实现ItemTouchHelper.Callback类,重写以下几个方法: - getMovementFlags:指定拖拽和滑动的方向,可以使用ItemTouchHelper.UP、ItemTouchHelper.DOWN、ItemTouchHelper.LEFT、ItemTouchHelper.RIGHT等常量。 - onMove:处理拖拽事件,通过交换两个Item的位置实现互相拖拽。 - onSwiped:处理滑动事件,可以在这个方法中实现删除Item的操作。 5. 在RecyclerView的Adapter中对Item的触摸事件进行监听,当用户按下item时,调用startDrag方法来开始拖拽。 6. 当拖拽结束时,将交换过位置的数据更新到对应的数据源中,并刷新RecyclerView。 通过以上步骤,就可以实现两个RecyclerView之间的item互相拖拽了。可以在同一个Activity或Fragment中同时显示这两个RecyclerView,或者在不同的页面中分别显示这两个RecyclerView。这样用户就可以通过拖拽的方式,将一个RecyclerView的item拖放到另一个RecyclerView中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值