RecyclerView实现Item可拖拽(拖动、删除)
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可拖拽(拖动、删除)相关推荐
- Android开发之RecyclerView的交互动画(实现拖拽和删除)
做RecyclerView做相关的动画效果的时候,用的最多的是v7包下的ItemTouchHelper类,这个类很强大,如有兴趣的童鞋可以自行翻看源码,接下来我带领大家实现RecyclerView相关 ...
- recycleView 滑动删除Item,拖拽切换Item,你想了解的都在这儿
滑动删除Item,拖拽切换Item,你想了解的都在这儿 概述 如果上两篇对RecyclerView介绍后,依然没有引起你的兴趣,那么下面关于RecyclerView的使用我相信一定会让你如获珍宝.直接 ...
- 安卓开发仿微信图片拖拽_Android 仿微信朋友圈发表图片拖拽和删除功能
朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...
- Android 仿微信朋友圈发表图片拖拽和删除功能
朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...
- 安卓开发仿微信图片拖拽_仿微信朋友圈发表图片拖拽和删除功能
原标题:仿微信朋友圈发表图片拖拽和删除功能 中国联通在香港公布了上市公司2017年中期业绩.2017年上半年,公司主要业绩指标持续向好,收入稳步回升,服务收入达到人民币1,241.1亿元,同比增长3. ...
- 一个可变布局列表,有9种布局item大小,每个item可拖拽切换位置
代码地址如下: http://www.demodashi.com/demo/11271.html 一.准备工作 准备一台安卓设备手机,4.4以上版本 本例子实现,一个可变布局列表,有9种布局item大 ...
- 原生js实现canvas画布中绘制、移动、拖拽、删除矩形(如简易截图工具)
功能描述 待图片上传并加载完成后,重新生成画布: 鼠标在画布区域内绘制,移动,拖拽,删除矩形(如截图工具一般): isboundary() 判断是否需要判断边界问题,默认false. 效果截图 实现代 ...
- 滑动删除Item,拖拽切换Item,你想了解的都在这儿
转载注明出处:http://blog.csdn.net/xiaohanluo/article/details/52330537 1. 概述 如果上两篇对RecyclerView介绍后,依然没有引起你的 ...
- 解决打开文件、文件夹、拖拽复制删除时鼠标卡顿
1.问题描述 打开文件.文件夹.拖拽文件复制删除时,鼠标总会卡一两秒,在需要处理大量文件时非常影响工作. 2.解决过程 通过任务管理器发现windows资源管理器在进行上述操作时cpu占用会迅速拉高, ...
最新文章
- AS3.0编程 So本地数据存储(“超级cookies”)--AS3:Local SharedObject
- python画蝴蝶_python画蝴蝶曲线图的实例
- pythontcp_TCP编程
- 郑州军办计算机学校,郑州市国防科技学校2019级新生开启军训模式
- Marble原理之线程中断
- 2015-03-12---外观模式,建造者模式(附代码),观察者模式(附代码),boost库应用
- Synchronized的实现原理(一)
- 第六章 图 学习小结
- 11GR DATAGRUAD环境BROKER配置Fast-Start Failover
- ospf避免环路_【网络干货】超全的OSPF路由协议技术汇总解析
- 配置csrf_django 入门第一课 配置文件
- Exar签署最终协议 5900万美元收购Hifn
- (翻译)《介绍 GENEVA Beta 1 白皮书》(3)
- 详解Linux操作系统的系统备份与恢复
- PHP一个文件内多个php代码段的写法
- mysql8下的密码过期问题以及navicat登录mysql报错的问题
- oracle 19602,Oracle CPU Costing
- python通讯录管理系统设计_通讯录程序设计报告
- Gram 矩阵及其主要性质
- 13个有意思的网站,你一定要看