RecyclerView实现拖拽功能

前言:

RecyclerView如果实现拖拽功能,其实无非耗费太多时间,因为google已经帮我们封装好了,有相关接口暴露出来提供给我们使用,站在巨人肩膀上,我们试一试ItemTouchHelper

先看个简陋的效果图

step1:

现在布局文件加入RecyclerView,并在代码中初始化并绑定,代码简单不多说

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>


   this.mRecyView = (RecyclerView) findViewById(R.id.recyView);
        mRecyView.setLayoutManager(new GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false));
        mDatas = new ArrayList<>();
        mAdapter = new MyAdapter(this, mDatas, mItemHelper, vb);
        mRecyView.setAdapter(mAdapter);

给RecyclerView设置个模拟数据,便于我们测试看效果

        for (int i = 0; i < 100; i++)
            mDatas.add("加油小伙子!  " + i);
        mAdapter.notifyDataSetChanged();

添加适配器

/**
 * Created by Administrator on 2018/3/14
 */

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private Context mContext;
    private List<String> mDatas;
    private ItemTouchHelper mItemHelper;
    private Vibrator mVb;

    public MyAdapter(Context mContext, List<String> mDatas, ItemTouchHelper itemHelper, Vibrator vb) {
        this.mContext = mContext;
        this.mDatas = mDatas;
        this.mItemHelper = itemHelper;
        this.mVb = vb;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item, null, false));
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        holder.tv.setText(mDatas.get(position));
        holder.tv.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (position > 30) {
                    mItemHelper.startDrag(holder);
                }

                return false;
            }
        });

    }

    @Override
    public int getItemCount() {
        return mDatas.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        private View mView;
        private TextView tv;

        public MyViewHolder(View itemView) {
            super(itemView);
            tv = (TextView) itemView.findViewById(R.id.tv);
        }
    }

step2:

这是关键的地方,初始化ItemTouchHelper,并让RecyclerView绑定

 ItemTouchHelper mItemHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            Log.e("hsjkkk", "getMovementFlags()");
            if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
                        ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
                final int swipeFlags = 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            } else {
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                final int swipeFlags = 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            }
        }

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            Log.e("hsjkkk", "onMove()");
            //得到当拖拽的viewHolder的Position
            int fromPosition = viewHolder.getAdapterPosition();
            //拿到当前拖拽到的item的viewHolder
            int toPosition = target.getAdapterPosition();
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(mDatas, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(mDatas, i, i - 1);
                }
            }
            mAdapter.notifyItemMoved(fromPosition, toPosition);
            return true;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//                Toast.makeText(MainActivity.this, "拖拽完成 方向" + direction, Toast.LENGTH_SHORT).show();
            Log.e("hsjkkk", "拖拽完成 方向" + direction);

        }

        @Override
        public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
            super.onSelectedChanged(viewHolder, actionState);
            Log.e("hsjkkk", "onSelectedChanged()");
            if (actionState != ItemTouchHelper.ACTION_STATE_IDLE)
                viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
        }

        @Override
        public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            super.clearView(recyclerView, viewHolder);
            Log.e("hsjkkk", "clearView()");
            viewHolder.itemView.setBackgroundColor(0);

        }

        //重写拖拽不可用
        @Override
        public boolean isLongPressDragEnabled() {
            Log.e("hsjkkk", "isLongPressDragEnabled()");
            return false;
        }


    });
 //拖拽功能
        mItemHelper.attachToRecyclerView(mRecyView);

实现ItemTouchHelper类

  ItemTouchHelper mItemHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            Log.e("hsjkkk", "getMovementFlags()");
            if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
                        ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
                final int swipeFlags = 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            } else {
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                final int swipeFlags = 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            }
        }

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            Log.e("hsjkkk", "onMove()");
            //得到当拖拽的viewHolder的Position
            int fromPosition = viewHolder.getAdapterPosition();
            //拿到当前拖拽到的item的viewHolder
            int toPosition = target.getAdapterPosition();
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(mDatas, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(mDatas, i, i - 1);
                }
            }
            mAdapter.notifyItemMoved(fromPosition, toPosition);
            return true;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//                Toast.makeText(MainActivity.this, "拖拽完成 方向" + direction, Toast.LENGTH_SHORT).show();
            Log.e("hsjkkk", "拖拽完成 方向" + direction);

        }

        @Override
        public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
            super.onSelectedChanged(viewHolder, actionState);
            Log.e("hsjkkk", "onSelectedChanged()");
            if (actionState != ItemTouchHelper.ACTION_STATE_IDLE)
                viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
        }

        @Override
        public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            super.clearView(recyclerView, viewHolder);
            Log.e("hsjkkk", "clearView()");
            viewHolder.itemView.setBackgroundColor(0);

        }

        //重写拖拽不可用
        @Override
        public boolean isLongPressDragEnabled() {
            Log.e("hsjkkk", "isLongPressDragEnabled()");
            return false;
        }


    });

说一下这几个回调接口意思

getMovementFlags()是设置是否滑动时间,以及拖拽的方向,如果是列表布局的话则拖拽方向有DOWN和UP,如果是网格布局的话有DOWN和UP和LEFT和RIGHT4个方向

onMove()是在拖动的过程中不断回调的方法,在这里可以写上一些交换数据的逻辑

onSwiped()是拖动完成以后会回调的方法

onSelectedChanged()是在选中以后回调的方法

clearView()是拖放完成以后view被释放的方法

isLongPressDragEnabled()是重写是否允许item被拖拽的方法

demo中为了测试写的是positation>30的时候才允许拖拽

 

 

 

 

 

 

 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现两个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中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值