Android recyclerview实现拖拽排序和侧滑删除

Recyclerview现在基本已经替代Listview了,RecyclerView也越来越好用了  当我们有实现条目的拖拽排序和侧滑删除时  可以直接时候Recyclerview提供的API就可以直接实现了
先贴上主要代码

private void initveiw() { ArrayList<String> items = new ArrayList<>(Arrays.asList("itme1", "item2", "itme3", "item4", "item5", "item6", "item7", "item8", "itme9", "item10", "itme11", "item12", "item13", "item14", "item15", "item16")); recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)); SimpleAdapter adapter = new SimpleAdapter(items); recyclerView.setAdapter(adapter); ItemTouchHelper helper = new ItemTouchHelper(new MyItemTouchCallback(adapter)); helper.attachToRecyclerView(recyclerView); } public class MyItemTouchCallback extends ItemTouchHelper.Callback{ private SimpleAdapter adapter; public MyItemTouchCallback(SimpleAdapter adapter) { this.adapter = adapter; } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlag; int swipeFlag; RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if (manager instanceof GridLayoutManager){ dragFlag = ItemTouchHelper.DOWN | ItemTouchHelper.UP | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; swipeFlag = 0; }else{ dragFlag = ItemTouchHelper.DOWN | ItemTouchHelper.UP; swipeFlag = ItemTouchHelper.END | ItemTouchHelper.START; } return makeMovementFlags(dragFlag,swipeFlag); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); if (fromPosition < toPosition ){ for (int i = fromPosition ;i<toPosition ;i++){ Collections.swap(adapter.getDataList(),i,i+1); } }else{ for (int i= fromPosition; i>toPosition; i--){ Collections.swap(adapter.getDataList(),i ,i-1); } } recyclerView.getAdapter().notifyItemMoved(fromPosition,toPosition); return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { int position = viewHolder.getAdapterPosition(); if (direction == ItemTouchHelper.END | direction==ItemTouchHelper.START){ adapter.getDataList().remove(position); adapter.notifyItemRemoved(position); } } @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); if (actionState==ItemTouchHelper.ACTION_STATE_DRAG){ viewHolder.itemView.setBackgroundColor(Color.BLUE); } } @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); viewHolder.itemView.setBackgroundColor(0); } }

步骤:

创建 ItemTouchHelper 对象时候,需要我们传入一个实现了 ItemTouchHelper.Callback 接口的对象。而排序和删除的逻辑都封装在了这个 ItemTouchHelper.Callback 的对象里面了。

private void initveiw() { ArrayList<String> items = new ArrayList<>(Arrays.asList("itme1", "item2", "itme3", "item4", "item5", "item6", "item7", "item8", "itme9", "item10", "itme11", "item12", "item13", "item14", "item15", "item16")); recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)); SimpleAdapter adapter = new SimpleAdapter(items); recyclerView.setAdapter(adapter); ItemTouchHelper helper = new ItemTouchHelper(new MyItemTouchCallback(adapter)); helper.attachToRecyclerView(recyclerView); }

实现ItemTouchHelper.Callback 接口后有三个方法需要重写:

getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) :设置滑动类型的标记。需要设置两种类型的 flag ,即 dragFlags 和 swipeFlags ,分别代表着拖拽标记和滑动标记。最后需要调用 makeMovementFlags(dragFlags,
 swipeFlags)方法来合成返回。
onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) :当用户拖拽列表某个 item 时会回调。很明显,拖拽排序的代码应该在这个方法中实现。

onSwiped(RecyclerView.ViewHolder viewHolder, int direction) :当用户滑动列表某个 item 时会回调。所以侧滑删除的代码应该在这个方法中实现。
下面是重写的几个方法:

第一个,getMovementFlags方法

@Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlag; int swipeFlag; RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if (manager instanceof GridLayoutManager){ dragFlag = ItemTouchHelper.DOWN | ItemTouchHelper.UP | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; swipeFlag = 0; }else{ dragFlag = ItemTouchHelper.DOWN | ItemTouchHelper.UP; swipeFlag = ItemTouchHelper.END | ItemTouchHelper.START; } return makeMovementFlags(dragFlag,swipeFlag); }

这个方法里面根据LayoutManager分了两种情况,根据自己的情况去分
在GridLayoutManager中只能上下左右拖拽但是不能侧滑删除,所以swipFlag = 0;swipeFlag的值ItemTouchHelper.END是右滑删除,ItemTouchHelper.START是左滑删除
最后调用makeMovementFlags方法合成返回

第二个,onMove方法

@Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); if (fromPosition < toPosition ){ for (int i = fromPosition ;i<toPosition ;i++){ Collections.swap(adapter.getDataList(),i,i+1); } }else{ for (int i= fromPosition; i>toPosition; i--){ Collections.swap(adapter.getDataList(),i ,i-1); } } recyclerView.getAdapter().notifyItemMoved(fromPosition,toPosition); return true; }

这个方法是用户在拖拽 item 的时候调用。所以关于列表排序的代码应该写在这里。方法参数中的 viewHolder 代表的是用户当前拖拽的 item ,而 target 代表的是被用户拖拽所覆盖的那个 item 。所以在 onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) 方法中的逻辑就是把 fromPosition 至 toPosition 为止改变它们的位置。

第三个,onSwiped方法

@Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { int position = viewHolder.getAdapterPosition(); if (direction == ItemTouchHelper.END | direction==ItemTouchHelper.START){ adapter.getDataList().remove(position); adapter.notifyItemRemoved(position); } }

这个方法是在用户侧滑的时候调用的 ,在里面对adapter的数据进行删除就可以了

最后两个方法

@Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); if (actionState==ItemTouchHelper.ACTION_STATE_DRAG){ viewHolder.itemView.setBackgroundColor(Color.BLUE); } } @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); viewHolder.itemView.setBackgroundColor(0); } }

就是优化的方法,第一个是选择条目改变状态,第二个是手指抬起之后恢复条目状态

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-07-29 15:00:04

Android recyclerview实现拖拽排序和侧滑删除的相关文章

android RecyclerView实现条目Item拖拽排序与滑动删除

效果演示 需求和技术分析 RecyclerView Item拖拽排序::长按RecyclerView的Item或者触摸Item的某个按钮. RecyclerView Item滑动删除:RecyclerView Item滑动删除:RecyclerView的Item滑动删除. 实现方案与技术 利用ItemTouchHelper绑定RecyclerView.ItemTouchHelper.Callback来实现UI更新,并且实现动态控制是否开启拖拽功能和滑动删除功能. 实现步骤 继承抽象类ItemTo

jquery实现图片拖拽排序

最近在研究Interface elements for jQuery(http://interface.eyecon.ro/),此插件封装了一些拖拽效果,并且使用非常简单,能轻松实现拖拽排序.购物车.博客首页排版等UI,所以模仿和讯的图片排序做了一个简单样例: 代码: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /&g

iOS_UI进阶【拖拽排序】的实现

导读 拖拽排序是新闻类的App可以说是必有的交互设计,如今日头条,网易新闻等.拖拽排序是一个交互体验非常好的设计,简单,方便. github地址:https://github.com/HelloYeah/DraggingSort 欢迎Star,予人玫瑰,手有余香. 今日头条的拖拽排序界面 我实现的长按拖拽排序效果 实现方案 1.给CollectionViewCell添加一个长按手势,通过协议把手势传递到collectionView所在的控制器中. - (void)awakeFromNib{ se

jquery拖拽排序简单实现方法(效果增强版)_jquery

本文实例讲述了jquery拖拽排序简单实现方法.分享给大家供大家参考,具体如下: 运行效果截图如下: 原来没有新建动作,分析代码后发现很容易增强~~ 代码如下: <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>测试的拖拽功能</title

Sortable.js拖拽排序使用方法解析_javascript技巧

最近公司项目经常用到一个拖拽 Sortable.js插件,所以有空的时候看了 Sortable.js 源码,总共1300多行这样,写的挺完美的. 官网: http://rubaxa.github.io/Sortable/ 拖拽的时候主要由这几个事件完成,     ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上     ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上     ondragover 事件:拖拽

jQuery拖拽排序插件制作拖拽排序效果(附源码下载)_jquery

使用jquery拖拽排序插件制作拖拽排序效果是一款非常实用的鼠标拖拽布局插件.效果图如下: 效果演示         源码下载 html代码: <h1>水平拖拽</h1> <div class="demo"> <div class="item item1"><span>1</span></div> <div class="item item2"><

dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法_php实例

在以前的一个公司内部管理系统(InnerOA)中,对于目录树的构造我采用的是dTree,实现无限级目录显示及右键菜单功能(右键菜单中包括:新建.修改.共享.删除.刷新等功能,如下图所示) 关于公司内部管理系统(InnerOA)中目录树的一些知识以后有时间将整理并提供源码. 但是dTree唯一遗憾的是不支持拖拽排序功能,这让我在完成InnerOA之后心里一直纠结的问题.在网上查看关于目录树的一些内容,dTree是我目前认为最符合我项目的一个.在一个偶然机会,发现了另一个强大的目录树,也就是本文所说

关于二级目录拖拽排序的实现(源码示例下载)_php实例

在开发项目中经常碰到二级目录形式.比如文章模块.产品模块,很多应多都基于两级分类形式.而普通的解决排序方案,不管是一级分类,还是多级分类,都是由管理员在后台手动编辑同级分类排序的值来设置排序,根据该值的大小决定显示的顺序.这样的操作方式比较烦琐.jQuery有对于排序采用拖拽方式来实现排序,从用户层面,这样的操作非常直观,操作简便.曾经在一个项目中,产品分类采用的是两级分类,显示如下图所示: 在排序问题上,决定使用jQuery的拖拽插件来实现:拖拽一级分类时,对一级分类进行排序:拖拽某一级分类下

jQuery实现div横向拖拽排序的简单实例_jquery

实例如下: <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>div横向拖拽排序</title> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script> <style type="text/css"