使用RecylerView完成拖动排序高仿qq侧滑删除功能

最近使用到Recylerview完成拖动排序,侧滑删除,在此记录一下。

需要使用到:ItemTouchHelper.Callback这个类。

效果图:

在有RecylerView的Activity中,除了设置Adapter还需要做的事情有:

MyItemTouchHelperCallback callback = new MyItemTouchHelperCallback(adapter); //此类继承ItemTouchHelper.Callback,这是帮助处理RecylerView拖动侧滑操作的辅助类
ItemTouchHelper helper = new ItemTouchHelper(callback); //用上面实例化的callback实例化一个ItemTouchHelper对象。套路代码,没啥好说的,固定做法
helper.attachToRecyclerView(recyclerView); //让help帮助处理recylerview的滑动,侧滑操作

Activity中的操作就这么简单。

接下来定义一个接口,这个接口是为了解除耦合,因为我看到有一些文章在activity中处理了onMove和onSwipe,抽象出来更好理解。

public interface OnMoveAndSwipeListener {
public boolean onItemMove(int fromPosition, int toPosition); //注意返回boolean哦
public void onItemDismiss(int position);
}

在RecylerView的Adapter中实现此接口,

复写上面的两个方法,

@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
//往下移动时,做数据交换
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(list,i,i+1);
}
}else{
//往上移动,做数据交换
for (int i = fromPosition; i >toPosition ; i--) {
Collections.swap(list,i,i-1);
}
}
notifyItemMoved(fromPosition,toPosition);
return true;
}
@Override
public void onItemDismiss(int position) {
//此例没有对侧滑做操作,如果需要就在此模仿onItemMove方法,删除对应位置的数据,并且刷新界面就可以了
}

这样Adapter的工作也就完成了,一样也很简单,都有固定的套路,注意大家看到的demo都是有个默认的动画,这个动画效果是你在设置RecylerView时,recylerview.setItemAnimator(参数);设置进去的,如果你没有调用此方法,则就是默认动画效果。

除了设置Adapter还需要做的事情有:

写一个类继承ItemTouchHelper.Callback,这就是最后一步了,也是本文最开始在Activity中实例化的类,

代码也不多:

public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {
MyAdapter adapter;
public MyItemTouchHelperCallback(MyAdapter adapter) {
this.adapter = adapter;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//复写此方法用来设置我需要处理哪些操作
//我要处理上下拖动,就设置up down,如果是gridview类型的recylerview,up,down,left,right都可以处理
final int moveMode = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
//本例没有处理侧滑,如果需要处理侧滑,就把注释取消掉
//final int swipeMode = ItemTouchHelper.START | ItemTouchHelper.END;
Log.e("getMovementFlags","getMovementFlags");
return makeMovementFlags(moveMode, 0);//不处理什么,就传0
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//当你拖动时就会触发此回调,然后调用在adapter中复写的onItemMove方法,去交换数据
return adapter.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//如果你要处理侧滑就取消注释,逻辑和上面的onMove一样
// adapter.onItemDismiss(viewHolder.getAdapterPosition());
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
//此方法在你选中一个item拖动时触发,所以你可以在这里给选中的item设置一个背景色,用于高亮提示你选中了这个背景色
super.onSelectedChanged(viewHolder, actionState);
if (actionState!= ItemTouchHelper.ACTION_STATE_IDLE){
viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
}
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//因为你设置了背景色,所以在你不选中的时候,要取消掉这个背景色。
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setBackgroundColor(0);
}
}

到此为止,一个简单的拖动和侧滑就完成了,其实拖动和侧滑的逻辑都是一样的,按着上面的步骤来,效果就出来了。

上面只是一个简单的效果。把上面的效果实现了,接下来看更进阶一点的效果:

RecycleViewSwipeDismiss

要做到上述的效果,先说一下上面的逻辑:

首先他的每个Item的布局是两层:

<?xml version="1.0" encoding="utf-8"?>
<!--背景view,用于提示用户操作结果-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl_background"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_done"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:src="@mipmap/bt_ic_done_white_24" />
<ImageView
android:id="@+id/iv_schedule"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:src="@mipmap/bt_ic_schedule_white_24" />
<!--滑动操作的view-->
<LinearLayout
android:id="@+id/ll_item"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<TextView
android:id="@+id/tv_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="Item" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/ll_item"
android:background="#B2B2b2" />
</RelativeLayout>

原理:全屏的linearlayout负责侧滑效果,而根布局是有颜色有图片的那一层,因为linearlayout被滑走了,所以根布局以及上面的图片就出来了。

需要在MyItemTouchHelperCallback中重新复写的几个方法,以及多复写的几个方法:

<span style="white-space:pre"> </span> @Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 释放View时回调,清除背景颜色,隐藏图标
// 默认是操作ViewHolder的itemView,这里调用ItemTouchUIUtil的clearView方法传入指定的view
getDefaultUIUtil().clearView(((SampleAdapter.ItemViewHolder) viewHolder).vItem);
((SampleAdapter.ItemViewHolder) viewHolder).vBackground.setBackgroundColor(Color.TRANSPARENT);
((SampleAdapter.ItemViewHolder) viewHolder).ivSchedule.setVisibility(View.GONE);
((SampleAdapter.ItemViewHolder) viewHolder).ivDone.setVisibility(View.GONE);
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
// 当viewHolder的滑动或拖拽状态改变时回调
if (viewHolder != null) {
// 默认是操作ViewHolder的itemView,这里调用ItemTouchUIUtil的clearView方法传入指定的view
getDefaultUIUtil().onSelected(((SampleAdapter.ItemViewHolder) viewHolder).vItem);
}
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
// ItemTouchHelper的onDraw方法会调用该方法,可以使用Canvas对象进行绘制,绘制的图案会在RecyclerView的下方
// 默认是操作ViewHolder的itemView,这里调用ItemTouchUIUtil的clearView方法传入指定的view
getDefaultUIUtil().onDraw(c, recyclerView, ((SampleAdapter.ItemViewHolder) viewHolder).vItem, dX, dY, actionState, isCurrentlyActive);
if (dX > 0) { // 向左滑动是的提示
((SampleAdapter.ItemViewHolder) viewHolder).vBackground.setBackgroundResource(R.color.colorDone);
((SampleAdapter.ItemViewHolder) viewHolder).ivDone.setVisibility(View.VISIBLE);
((SampleAdapter.ItemViewHolder) viewHolder).ivSchedule.setVisibility(View.GONE);
}
if (dX < 0) { // 向右滑动时的提示
((SampleAdapter.ItemViewHolder) viewHolder).vBackground.setBackgroundResource(R.color.colorSchedule);
((SampleAdapter.ItemViewHolder) viewHolder).ivSchedule.setVisibility(View.VISIBLE);
((SampleAdapter.ItemViewHolder) viewHolder).ivDone.setVisibility(View.GONE);
}
}
@Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
// ItemTouchHelper的onDrawOver方法会调用该方法,可以使用Canvas对象进行绘制,绘制的图案会在RecyclerView的上方
// 默认是操作ViewHolder的itemView,这里调用ItemTouchUIUtil的clearView方法传入指定的view
getDefaultUIUtil().onDrawOver(c, recyclerView, ((SampleAdapter.ItemViewHolder) viewHolder).vItem, dX, dY, actionState, isCurrentlyActive);
}
});

用getDefaultUIUtil()的方法指定滑动操作的是linearlayout,所以每次被滑走的只有linearlayout。其他的操作都是一样的。

(0)

相关推荐

  • Android项目实战之仿网易新闻的页面(RecyclerView )

    本文实例实现一个仿网易新闻的页面,上面是轮播的图片,下面是 RecyclerView 显示新闻列表,具体内容如下 错误方法 <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...> <ViewPager ... /> <android.support.v7.widget.RecyclerView .../> </LinearLayout> 这样布局

  • Android RecyclerView滑动删除和拖动排序

    本篇是接着上面三篇之后的一个对RecyclerView的介绍,这里多说两句,如果你还在使用ListView的话,可以放弃掉ListView了.RecyclerView自动帮我们缓存Item视图(ViewHolder),允许我们自定义各种动作的动画和分割线,允许我们对Item进行一些手势操作.另外,因为Design库的推出大大方便我们编写带有Material风格的App,而ListView是不兼容这个库的,比如滑动的相互协调,只有RecyclerView能做到. 先看本篇内容的效果图: 效果内容主

  • Android RecyclerView 上拉加载更多及下拉刷新功能的实现方法

    RecyclerView 已经出来很久了,但是在项目中之前都使用的是ListView,最近新的项目上了都大量的使用了RecycleView.尤其是瀑布流的下拉刷新,网上吧啦吧啦没有合适的自己总结了一哈. 先贴图上来看看: 使用RecyclerView实现上拉加载更多和下拉刷新的功能我自己有两种方式: 1.使用系统自带的Android.support.v4.widget.SwipeRefreshLayout这个控价来实现. 2.自定义的里面带有RecyleView的控件. 使用RecycleVie

  • Android中RecyclerView布局代替GridView实现类似支付宝的界面

    单纯使用GridView 通用的两种给GridView 添加分割线的方法:http://stackoverflow.com/questions/7132030/android-gridview-draw-dividers 给Gridview 添加分割线,也就是实现网格布局,不清楚谷歌为什么没有给Gridview 添加一个类似 ListView 的Divider 属性,因此就需要我们自己去添加分割线, 目前两种方法,第一种是 利用GridView 的  android:horizontalSpac

  • 使用RecylerView完成拖动排序高仿qq侧滑删除功能

    最近使用到Recylerview完成拖动排序,侧滑删除,在此记录一下. 需要使用到:ItemTouchHelper.Callback这个类. 效果图: 在有RecylerView的Activity中,除了设置Adapter还需要做的事情有: MyItemTouchHelperCallback callback = new MyItemTouchHelperCallback(adapter); //此类继承ItemTouchHelper.Callback,这是帮助处理RecylerView拖动侧滑

  • Android使用Item Swipemenulistview实现仿QQ侧滑删除功能

    大家都用过QQ,肯定有人好奇QQ滑动删除Item的效果是怎样实现的,其实我们使用Swipemenulistview就可以简单的实现.先看看我们项目中的效果: 使用的时候可以把Swipemenulistview作为一个library,也可以把Swipemenulistview的源码拷贝到我们的项目中来,使用步骤大致可以分为三步:1.在布局中配置:2.在Java代码中初始化配置:3.按钮点击事件的处理  1.在布局中配置 xml布局文件中只需要简单使用这个自定义的ListView就行了,需要注意的是

  • Android高仿QQ小红点功能

    先给大家展示下效果图: 代码已上传至Github:高仿QQ小红点,如对您有帮助,欢迎star~感谢 绘制贝塞尔曲线: 主要是当在一定范围内拖拽时算出固定圆和拖拽圆的外切直线以及对应的切点,就可以通过path.quadTo()来绘制二阶贝塞尔曲线了~ 整体思路: 1.当小红点静止时,什么都不做,只需要给自定义小红点QQBezierView(extends TextView)添加一个.9文件当背景即可 2.当滑动时,通过getRootView()获得顶级根View,然后new一个DragView (

  • iOS中仿QQ侧滑菜单功能

    UITabBarController做QQ侧滑菜单效果: 首先要了解UITabBarController的层级结构: UITabBarController加载的其它UIViewController的View都是被添加在UITransitionView上(这是一个私有API),UITransitionView在self.view的0层,UITabBar在的第一层. 所以我的思路是这样的: UITransitionView与UITabBar转移到一个新的View1上去,作为滑动的部分: 在View1

  • Android 高仿QQ 沉浸式状态栏

    前言: 在进入今天正题前,还是老样子先谈谈感想吧,最近感觉整个都失去了方向感,好迷茫!找工作又失败了,难道Android真的饱和了?这两天我一直没出门,除了下楼哪外卖就是宅宿舍了,静想了许久,我还是不能忘了初心,我相信我找不到工作的原因有很多,最关键的还是要技术够硬才行啊,奔跑吧孩子!接下来我就给大家介绍怎样快速打造沉浸式状态栏吧,虽然感觉有点相见恨晚,但其实不完! 一:何为沉浸式状态栏? 沉浸式状态栏是Google从Android 4.4开始,给我们开发者提供的一套能透明的系统ui样式,这样样

  • Android 高仿QQ图片选择器

    当做一款APP,需要选择本地图片时,首先考虑的无疑是系统相册,但是Android手机五花八门,再者手机像素的提升,大图无法返回等异常因数,导致适配机型比较困难,微信.QQ都相继的在自己的APP里集成了图片选择功能,放弃了系统提供的图片选择器,这里仿造QQ做了一个本地图片选择器,PS:之前有人说"仿"写成"防"了,今儿特意注意了下,求不错. 先上一张效果图,无图无真相啊~~~ 实现的效果大概是这样的: 1.单选:跳转到本地图片选择文件夹,选择文件夹后,进入到该文件夹下

  • Android_UI 仿QQ侧滑菜单效果的实现

    相信大家对QQ侧滑菜单的效果已经不陌生了吧,侧滑进入个人头像一侧,进行对头像的更改,我的收藏,QQ钱包,我的文件等一系列的操作,今天呢,主要是实现进入侧滑菜单的这一效果原理进行分析. 主要思路分析 1.首先写一个SlideMenu 继承一个帧布局FrameLayout ,因为如果继承自ViewGroup的话,需要我们自己来实现onMeasure方法,而该方法的实现一般比较麻烦且没有必要,所以选择继承系统的已有的控件FrameLayout,不用其他控件是因为FrameLayout最轻量级 2.在布

  • Android自定义SwipeLayout仿QQ侧滑条目

    Android自定义SwipeLayout仿QQ侧滑条目,供大家参考,具体内容如下 先看动图 看布局文件 activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent

  • iOS高仿微信表情输入功能代码分享

    最近项目需求,要实现一个类似微信的的表情输入,于是把微信的表情扒拉出来,实现了一把.可以从这里下载源码.看起来表情输入没有多少东西,不外乎就是用NSTextAttachment来实现图文混排,结果在实现的过程中遇到了很多小问题,接下来会一一介绍遇到过的坑.先上一张效果图: 一.实现表情选择View(WKExpressionView) 具体的实现就不细说了,主要功能就是点击表情时,将对应表情的图片名称通知给delegate. 二.实现表情textView(WKExpressionTextView)

  • Android自定义View 仿QQ侧滑菜单的实现代码

    先看看QQ的侧滑效果 分析一下 先上原理图(不知道能否表达的清楚 ==) -首先这里使用了 Android 的HorizontalScrollView 水平滑动布局作为容器,当然我们需要继承它自定义一个侧滑视图 - 这个容器里面有一个父布局(一般用LinerLayout,本demo用的是),这个父布局里面有且只有两个子控件(布局),初始状态菜单页的位置在Y轴上存在偏移这样可以就可以形成主页叠在菜单页的上方的视觉效果:然后在滑动的过程程中 逐渐修正偏移,最后菜单页和主页并排排列.原理搞清了实现起来

随机推荐