recycleView 滑动删除Item,拖拽切换Item,你想了解的都在这儿
来源:互联网 发布:酷狗铃声制作专家 mac 编辑:程序博客网 时间:2024/05/01 03:59
滑动删除Item,拖拽切换Item,你想了解的都在这儿
概述
如果上两篇对RecyclerView介绍后,依然没有引起你的兴趣,那么下面关于RecyclerView的使用我相信一定会让你如获珍宝。直接看运行效果。
用ListView或者GridView实现上图中的功能非常麻烦,而如果用RecyclerView来实现,则非常简单。
如果对RecyclerView还没有认识的同学,可以查看这两篇文章。
RecyclerView使用一
RecyclerView使用二
ItemTouchHelper&ItemToucheHelper.CallBack
要实现上面的效果,代码很简单,只需要添加以下代码。
mItemTouchHelper = new ItemTouchHelper(mItemTouchCallBack);mItemTouchHelper.attachToRecyclerView(mRecyclerView);
ItemTouchHelper
主要用于对RecyclerView滑动删除和拖拽切换提供支持,它支持所有的类型的布局管理器LayoutManager。它只有一个构造函数,必须传入ItemToucheHelper.CallBack
这个类的实例化对象。
ItemToucheHelper.CallBack
它可以控制用户的哪些行为是可以操控列表的Item的,当用户进行了这些操作,它会收到回调。它有几个重要的回调方法。
mItemTouchCallBack = new ItemTouchHelper.Callback() { /** * 设置滑动类型标记 * * @param recyclerView * @param viewHolder * @return * 返回一个整数类型的标识,用于判断Item那种移动行为是允许的 */ @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { return makeMovementFlags(0,ItemTouchHelper.START | ItemTouchHelper.END); } /** * Item是否支持长按拖动 * * @return * true 支持长按操作 * false 不支持长按操作 */ @Override public boolean isLongPressDragEnabled() { return false; } /** * Item是否支持滑动 * * @return * true 支持滑动操作 * false 不支持滑动操作 */ @Override public boolean isItemViewSwipeEnabled() { return true; } /** * 拖拽切换Item的回调 * * @param recyclerView * @param viewHolder * @param target * @return * 如果Item切换了位置,返回true;反之,返回false */ @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { return true; } /** * 滑动删除Item * * @param viewHolder * @param direction * Item滑动的方向 */ @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { mAdapter.delete(viewHolder.getAdapterPosition()); } /** * Item被选中时候回调 * * @param viewHolder * @param actionState * 当前Item的状态 * ItemTouchHelper.ACTION_STATE_IDLE 闲置状态 * ItemTouchHelper.ACTION_STATE_SWIPE 滑动中状态 * ItemTouchHelper#ACTION_STATE_DRAG 拖拽中状态 */ @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { // item被选中的操作 if(actionState != ItemTouchHelper.ACTION_STATE_IDLE) { viewHolder.itemView.setBackgroundResource(R.color.md_gray); } super.onSelectedChanged(viewHolder, actionState); } /** * 移动过程中绘制Item * * @param c * @param recyclerView * @param viewHolder * @param dX * X轴移动的距离 * @param dY * Y轴移动的距离 * @param actionState * 当前Item的状态 * @param isCurrentlyActive * 如果当前被用户操作为true,反之为false */ @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { float x = Math.abs(dX) + 0.5f; float width = viewHolder.itemView.getWidth(); float alpha = 1f - x / width; viewHolder.itemView.setAlpha(alpha); super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } /** * 移动过程中绘制Item * * @param c * @param recyclerView * @param viewHolder * @param dX * X轴移动的距离 * @param dY * Y轴移动的距离 * @param actionState * 当前Item的状态 * @param isCurrentlyActive * 如果当前被用户操作为true,反之为false */ @Override public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } /** * 用户操作完毕或者动画完毕后会被调用 * * @param recyclerView * @param viewHolder */ @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { // 操作完毕后恢复颜色 viewHolder.itemView.setBackgroundResource(R.color.md_white); viewHolder.itemView.setAlpha(1.0f); super.clearView(recyclerView, viewHolder); }};
可以看见,其实用户的行为都被官方提供的v7包给封装了一层,只暴露出几个重要的方法,也就是说滑动删除和拖拽切换主要的操作行为都在ItemToucheHelper.CallBack
中,我们主要关注它就行了。
滑动删除
RecyclerView的具体使用就不再次贴代码了,不清楚的同学可以查看RecyclerView使用这篇文章。看一下滑动删除的ItemToucheHelper.CallBack
的实现。
mItemTouchCallBack = new ItemTouchHelper.Callback() { /** * 设置滑动类型标记,可从两端滑动Item */ @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { return makeMovementFlags(0,ItemTouchHelper.START | ItemTouchHelper.END); } /** * 设置Item不支持长按拖动 */ @Override public boolean isLongPressDragEnabled() { return false; } /** * Item支持滑动 */ @Override public boolean isItemViewSwipeEnabled() { return true; } /** * 滑动删除Item的操作 */ @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { mAdapter.delete(viewHolder.getAdapterPosition()); } /** * Item被选中时候,改变Item的背景 */ @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { // item被选中的操作 if(actionState != ItemTouchHelper.ACTION_STATE_IDLE) { viewHolder.itemView.setBackgroundResource(R.color.md_gray); } super.onSelectedChanged(viewHolder, actionState); } /** * 移动过程中重新绘制Item,随着滑动的距离,设置Item的透明度 */ @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { float x = Math.abs(dX) + 0.5f; float width = viewHolder.itemView.getWidth(); float alpha = 1f - x / width; viewHolder.itemView.setAlpha(alpha); super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } /** * 用户操作完毕或者动画完毕后调用,恢复item的背景和透明度 */ @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { // 操作完毕后恢复颜色 viewHolder.itemView.setBackgroundResource(R.color.md_white); viewHolder.itemView.setAlpha(1.0f); super.clearView(recyclerView, viewHolder); }};
在getMovementFlags()
方法中,调用了一个已经有的方法makeMovementFlags(int dragFlags, int swipeFlags)
,它用于创建一个滑动类型标记,有两个参数,第一个参数是拖拽的标记,第二个参数是滑动的标记。在这里我设置不可拖拽Item(传入0),可滑动Item的两端。
isLongPressDragEnabled
返回了false,让Item不会触发长按事件。
isItemViewSwipeEnabled()
返回了true,让Item支持滑动操作。
在onSelectedChanged()
方法中当Item的状态为滑动或者拖拽时候,改变Item背景。
在onChildDraw()
方法中处理了Item滑动操作,首先根据滑动距离改变了Item的透明度,然后调用父类方法,让Item根据手势滑动。
在clearView()
中,恢复了Item的背景和透明度。
在onSwiped()
方法中,调用自定的Adapter中的delete()
方法,将该位置的数据删除,并重新绘制列表。
public void delete(int position) { if(position < 0 || position > getItemCount()) { return; } mData.remove(position); notifyItemRemoved(position);}
最后实现的效果如下图。
拖拽切换
拖拽切换和滑动删除思路相同,只不过在处理过程有一些不同。网易新闻在添加栏目时候,就有网格的列表,长按之后可以拖拽切换Item,可以参考一下,也做个类似的demo。先看下ItemToucheHelper.CallBack
的实现。
mItemTouchCallBack = new ItemTouchHelper.Callback() { /** * 设置滑动类型标记 * * @param recyclerView * @param viewHolder * @return * 返回一个整数类型的标识,用于判断Item那种移动行为是允许的 */ @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { return makeMovementFlags(ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT | ItemTouchHelper.DOWN | ItemTouchHelper.UP, 0); } /** * Item是否支持长按拖动 * * @return * true 支持长按操作 * false 不支持长按操作 */ @Override public boolean isLongPressDragEnabled() { return true; } /** * Item是否支持滑动 * * @return * true 支持滑动操作 * false 不支持滑动操作 */ @Override public boolean isItemViewSwipeEnabled() { return false; } /** * 拖拽切换Item的回调 * * @param recyclerView * @param viewHolder * @param target * @return * 如果Item切换了位置,返回true;反之,返回false */ @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { mAdapter.move(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; } /** * Item被选中时候回调 * * @param viewHolder * @param actionState * 当前Item的状态 * ItemTouchHelper.ACTION_STATE_IDLE 闲置状态 * ItemTouchHelper.ACTION_STATE_SWIPE 滑动中状态 * ItemTouchHelper#ACTION_STATE_DRAG 拖拽中状态 */ @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { // item被选中的操作 if(actionState != ItemTouchHelper.ACTION_STATE_IDLE) { viewHolder.itemView.setBackgroundResource(R.color.md_gray); } super.onSelectedChanged(viewHolder, actionState); } /** * 用户操作完毕或者动画完毕后会被调用 * * @param recyclerView * @param viewHolder */ @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { // 操作完毕后恢复颜色 viewHolder.itemView.setBackgroundResource(R.drawable.md_common_bg); super.clearView(recyclerView, viewHolder); }};
getMovementFlags()
中设置可上下左右拖拽Item,但是不能滑动Item。
isLongPressDragEnabled()
设置为true,Item会出发长按事件
isItemViewSwipeEnabled()
设置为false,Item不可滑动
onSelectedChanged()
设置了Item被选中时候的背景
clearView()
恢复了Item的背景
onMove()
调用了自定义的Adapter中的move()
方法,将数据放到新的位置,并且重新绘制列表。
public void move(int fromPosition, int toPosition) { String prev = mData.remove(fromPosition); mData.add(toPosition > fromPosition ? toPosition - 1 : toPosition, prev); notifyItemMoved(fromPosition, toPosition);}
然后在设置RecyclerView的一些其他属性。
// 实例化ItemTouchHelpermmItemTouchHelper = new ItemTouchHelper(mItemTouchCallBack);// 实例化适配器mAdapter = new MDDragRvAdapter(MDMockData.getRvData());// 实例化布局管理器,网格样式mLayoutManager = new GridLayoutManager(this, 4, OrientationHelper.VERTICAL, false);// 设置适配器mRecyclerView.setAdapter(mAdapter);// 设置布局管理器mRecyclerView.setLayoutManager(mLayoutManager);// 关联RecyclerView和ItemTouchHelpermItemTouchHelper.attachToRecyclerView(mRecyclerView);
最后看一下实现的效果。
总结
在熟悉了ItemToucheHelper.CallBack
后,就能根据自己的需求实现各种效果,列表或者网格的都可以满足,使用起来非常简单。关于RecyclerView使用的介绍,也到此为止了。最后附上Demo工程的地址。
Demo工程地址
- recycleView 滑动删除Item,拖拽切换Item,你想了解的都在这儿
- 滑动删除Item,拖拽切换Item,你想了解的都在这儿
- RecycleView简单实现滑动删除Item
- RecycleView删除item问题
- RecycleView 删除指定item
- RecycleView 删除Item 遇到的问题
- 滑动删除ListView的Item
- listView 的item滑动删除
- RecycleView横向滑动item变大
- list滑动删除item
- RecycleView实现拖拽交换item位置
- 滑动删除ListView的Item的效果
- ListView的Item的滑动删除
- 关于RecycleView你想了解的或许在这里
- 赵雅智_AndroidUI_listview的item滑动删除效果
- AndroidUI_listview的item滑动删除效果
- 自定义滑动删除item的ListView。
- 简单的listview item滑动删除
- 带你开发一款给Apk中自动注入代码工具icodetools(完善篇)
- MySQL存储引擎中的MyISAM和InnoDB区别详解
- SoC嵌入式软件架构设计之二:内存管理单元的软、硬件协同设计
- mysql 创建sequence
- 1001害死人不偿命的(3n+1)猜想
- recycleView 滑动删除Item,拖拽切换Item,你想了解的都在这儿
- linux 内核/用户空间获取时间
- 用mapreduce计算wordCount和手机流量统计程序运行过程
- 想快速全面了解LoRa?看这篇就够了!
- NFS服务配置
- (六)文件描述符及最大打开文件个数
- vsftpd虚拟用户目录及权限分离
- PAT-乙级-1013
- 8.事件 事件发布程序