RecyclerView实现Item可拖拽(拖动、删除)

话不多说,先附上效果图:

ItemTouchHelper

这是一个RecyclerView的工具,提供了drag & swipe 的功能,可以帮助我们处理RecyclerView中的Item的拖拽和滑动事件。

        ItemTouchHelper helper = new ItemTouchHelper(new MyItemTouchHelperCallback(mAdapter,this));helper.attachToRecyclerView(mRecyclerView);

ItemTouchHelper.Callback

ItemTouchHelper.Callback是一个抽象类,里面有一些抽象方法需要开发者去重写。重写方法如下:

1. getMovementFlags(RecyclerView, ViewHolder) 2. onMove(RecyclerView, ViewHolder, ViewHolder)3. onSwiped(ViewHolder, int)4. onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)5. clearView(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder)6. isLongPressDragEnabled()7. isItemViewSwipeEnabled()

getMovementFlags(RecyclerView, ViewHolder)
这个方法是设置那些方向可以拖动和滑动RecyclerView中的item

    @Overridepublic int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {int dragFlag;    //拖动标记int swipeFlags;    //滑动标记//如果是表格布局,则可以上下左右的拖动,但是不能滑动if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {dragFlag = ItemTouchHelper.UP |ItemTouchHelper.DOWN |ItemTouchHelper.LEFT |ItemTouchHelper.RIGHT;swipeFlags = 0;}//如果是线性布局,那么只能上下拖动,只能左右滑动else {dragFlag = ItemTouchHelper.UP |ItemTouchHelper.DOWN;swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;}//通过makeMovementFlags生成最终结果return makeMovementFlags(dragFlag, swipeFlags);}

onMove(RecyclerView, ViewHolder, ViewHolder)
拖动item的回调方法,在这里面实现拖动需要做的事情,比如RecyclerView里面item的顺序交换,
传入的参数是被拖动item的ViewHolder和目标ViewHolder

    @Overridepublic boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {//被拖动的item位置int fromPosition = viewHolder.getLayoutPosition();//他的目标位置int targetPosition = target.getLayoutPosition();//为了降低耦合,使用接口让Adapter去实现交换功能mItemPositionListener.onItemSwap(fromPosition, targetPosition);return true;}

onSwiped(ViewHolder, int)
滑动item的回调方法,在这里面实现滑动需要做的事情,比如RecyclerView里面item的删除

    @Overridepublic void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {//为了降低耦合,使用接口让Adapter去实现交换功能mItemPositionListener.onItemMoved(viewHolder.getLayoutPosition());}

onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)
在每次item的状态变成拖拽 (ACTION_STATE_DRAG) 或者 滑动 (ACTION_STATE_SWIPE)的时候被调用。这是把你的item view变成激活状态的最佳地点。

    @Overridepublic void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {super.onSelectedChanged(viewHolder, actionState);//当开始拖拽的时候if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {//修改背景颜色viewHolder.itemView.setBackgroundColor(Color.LTGRAY);//手机振动Vibrator vibrator = (Vibrator)mContext.getSystemService(mContext.VIBRATOR_SERVICE);vibrator.vibrate(50);}}

clearView(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder)
item被放开或者动画完成的回调

    //当手指松开的时候@Overridepublic void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {viewHolder.itemView.setBackgroundColor(Color.TRANSPARENT);super.clearView(recyclerView, viewHolder);}

isLongPressDragEnabled()
设置是否长按才进入拖动
isItemViewSwipeEnabled()
设置是否支持滑动操作

简单Demo

开启振动权限

<uses-permission android:name="android.permission.VIBRATE"/>
public class MainActivity extends AppCompatActivity {private RecyclerView mRecyclerView;private MyAdapter mAdapter = new MyAdapter();private ItemTouchHelper helper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mRecyclerView = findViewById(R.id.mRecyclerView);GridLayoutManager mLinearLayoutManager;mLinearLayoutManager = new GridLayoutManager(this, 3);mRecyclerView.setLayoutManager(mLinearLayoutManager);mRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayout.HORIZONTAL));mRecyclerView.setAdapter(mAdapter);helper = new ItemTouchHelper(new MyItemTouchHelperCallback(mAdapter,this));helper.attachToRecyclerView(mRecyclerView);}/*** 数据默认写死的*/public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> implements OnItemPositionListener {private List<String> mDatas = new ArrayList<>();public MyAdapter() {for (int i = 0; i < 30; i++) {mDatas.add("item:" + i);}}@Overridepublic MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {return new MyHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle, parent, false));}@Overridepublic int getItemCount() {return mDatas.size();}@Overridepublic void onBindViewHolder(MyHolder holder, int position) {holder.tv.setText(mDatas.get(position));}@Overridepublic void onItemSwap(int from, int target) {
//            Collections.swap(mDatas, from, target);//交换数据String s = mDatas.get(from);mDatas.remove(from);mDatas.add(target,s);notifyItemMoved(from, target);}@Overridepublic void onItemMoved(int position) {mDatas.remove(position);notifyItemRemoved(position);}protected class MyHolder extends RecyclerView.ViewHolder {public TextView tv;public ImageView drag;public MyHolder(View itemView) {super(itemView);tv = itemView.findViewById(R.id.item_tv);drag = itemView.findViewById(R.id.item_drag);//                drag.setOnTouchListener(this);}/*          @Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {helper.startDrag(this);}return false;}*/}}}

ItemTouchHelper.Callback的isLongPressDragEnabled方法,让其返回false,表示我们不需要默认的长按开始拖动功能。然后在我们需要开始拖动的地方调用ItemTouchHelper.startDrag(ViewHolder viewHolder)方法即可开始拖动

public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {private OnItemPositionListener mItemPositionListener;private Context mContext;public MyItemTouchHelperCallback(OnItemPositionListener itemPositionListener, Context context) {mItemPositionListener = itemPositionListener;mContext = context;}@Overridepublic int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {int dragFlag;int swipeFlags;//如果是表格布局,则可以上下左右的拖动,但是不能滑动if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {dragFlag = ItemTouchHelper.UP |ItemTouchHelper.DOWN |ItemTouchHelper.LEFT |ItemTouchHelper.RIGHT;swipeFlags = 0;}//如果是线性布局,那么只能上下拖动,只能左右滑动else {dragFlag = ItemTouchHelper.UP |ItemTouchHelper.DOWN;swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;}//通过makeMovementFlags生成最终结果return makeMovementFlags(dragFlag, swipeFlags);}@Overridepublic boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {//被拖动的item位置int fromPosition = viewHolder.getLayoutPosition();//他的目标位置int targetPosition = target.getLayoutPosition();//为了降低耦合,使用接口让Adapter去实现交换功能mItemPositionListener.onItemSwap(fromPosition, targetPosition);return true;}@Overridepublic void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {//为了降低耦合,使用接口让Adapter去实现交换功能mItemPositionListener.onItemMoved(viewHolder.getLayoutPosition());}@Overridepublic void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {super.onSelectedChanged(viewHolder, actionState);//当开始拖拽的时候if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {viewHolder.itemView.setBackgroundColor(Color.LTGRAY);Vibrator vibrator = (Vibrator)mContext.getSystemService(mContext.VIBRATOR_SERVICE);vibrator.vibrate(50);}}//当手指松开的时候@Overridepublic void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {viewHolder.itemView.setBackgroundColor(Color.TRANSPARENT);super.clearView(recyclerView, viewHolder);}//禁止长按滚动交换,需要滚动的时候使用{@link ItemTouchHelper#startDrag(ViewHolder)}@Overridepublic boolean isLongPressDragEnabled() {//return false;return true;}
}
public interface OnItemPositionListener {//交换void onItemSwap(int from, int target);//滑动void onItemMoved(int position);
}

RecyclerView实现Item可拖拽(拖动、删除)相关推荐

  1. Android开发之RecyclerView的交互动画(实现拖拽和删除)

    做RecyclerView做相关的动画效果的时候,用的最多的是v7包下的ItemTouchHelper类,这个类很强大,如有兴趣的童鞋可以自行翻看源码,接下来我带领大家实现RecyclerView相关 ...

  2. recycleView 滑动删除Item,拖拽切换Item,你想了解的都在这儿

    滑动删除Item,拖拽切换Item,你想了解的都在这儿 概述 如果上两篇对RecyclerView介绍后,依然没有引起你的兴趣,那么下面关于RecyclerView的使用我相信一定会让你如获珍宝.直接 ...

  3. 安卓开发仿微信图片拖拽_Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

  4. Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

  5. 安卓开发仿微信图片拖拽_仿微信朋友圈发表图片拖拽和删除功能

    原标题:仿微信朋友圈发表图片拖拽和删除功能 中国联通在香港公布了上市公司2017年中期业绩.2017年上半年,公司主要业绩指标持续向好,收入稳步回升,服务收入达到人民币1,241.1亿元,同比增长3. ...

  6. 一个可变布局列表,有9种布局item大小,每个item可拖拽切换位置

    代码地址如下: http://www.demodashi.com/demo/11271.html 一.准备工作 准备一台安卓设备手机,4.4以上版本 本例子实现,一个可变布局列表,有9种布局item大 ...

  7. 原生js实现canvas画布中绘制、移动、拖拽、删除矩形(如简易截图工具)

    功能描述 待图片上传并加载完成后,重新生成画布: 鼠标在画布区域内绘制,移动,拖拽,删除矩形(如截图工具一般): isboundary() 判断是否需要判断边界问题,默认false. 效果截图 实现代 ...

  8. 滑动删除Item,拖拽切换Item,你想了解的都在这儿

    转载注明出处:http://blog.csdn.net/xiaohanluo/article/details/52330537 1. 概述 如果上两篇对RecyclerView介绍后,依然没有引起你的 ...

  9. 解决打开文件、文件夹、拖拽复制删除时鼠标卡顿

    1.问题描述 打开文件.文件夹.拖拽文件复制删除时,鼠标总会卡一两秒,在需要处理大量文件时非常影响工作. 2.解决过程 通过任务管理器发现windows资源管理器在进行上述操作时cpu占用会迅速拉高, ...

最新文章

  1. AS3.0编程 So本地数据存储(“超级cookies”)--AS3:Local SharedObject
  2. python画蝴蝶_python画蝴蝶曲线图的实例
  3. pythontcp_TCP编程
  4. 郑州军办计算机学校,郑州市国防科技学校2019级新生开启军训模式
  5. Marble原理之线程中断
  6. 2015-03-12---外观模式,建造者模式(附代码),观察者模式(附代码),boost库应用
  7. Synchronized的实现原理(一)
  8. 第六章 图 学习小结
  9. 11GR DATAGRUAD环境BROKER配置Fast-Start Failover
  10. ospf避免环路_【网络干货】超全的OSPF路由协议技术汇总解析
  11. 配置csrf_django 入门第一课 配置文件
  12. Exar签署最终协议 5900万美元收购Hifn
  13. (翻译)《介绍 GENEVA Beta 1 白皮书》(3)
  14. 详解Linux操作系统的系统备份与恢复
  15. PHP一个文件内多个php代码段的写法
  16. mysql8下的密码过期问题以及navicat登录mysql报错的问题
  17. oracle 19602,Oracle CPU Costing
  18. python通讯录管理系统设计_通讯录程序设计报告
  19. Gram 矩阵及其主要性质
  20. 13个有意思的网站,你一定要看

热门文章

  1. 2023.1.7单词打卡
  2. oracle支付预付款时账务处理,收到预付款账务处理是什么?
  3. 一个22岁黑社会青年说的话
  4. 客户端请求的端口号是什么?
  5. 基于UDP协议的局域网网络聊天工具
  6. 20222948 2022-2023-2 《网络攻防实践》第2周作业
  7. get最IN工控安全技术,看匡恩网络权威报告
  8. Dubbo的前世今生
  9. Untiy CurvedUI 的使用的bug修正
  10. Windows 下 Docker 与 VMware 共存