Android一步步带你在RecyclerView上面实现"拖放"和"滑动删除"功能
发布时间 - 2026-01-11 00:18:53 点击率:次先给大家展示下大概效果图:
Android上面有许多的教程, 库和示例, 在RecyclerView上面实现"拖放"和"滑动删除"功能. 尽管有更新, 更好的方法可用, 但是大多数人依然使用旧的View.OnDragListener和Roman Nurik的SwipeToDismiss方式. 除了经常使用GestureDetector和onInterceptTouchEvent之外, 几乎很少有人使用新的API, 要不然的话, 实现就复杂. 事实上真的有十分简单的方式在RecyclerView上面添加这两个功能. 它只要求一个类, 而且这个类已经是Android支持包的一部分.
ItemTouchHelper
ItemTouchHelper是一个强大的通用程序, 在RecyclerView上面添加"拖放"和"滑动删除"时, 你所需要做的所有事情, 它都会负责处理. 它是RecyclerView.ItemDecoration的子类, 这意味着它可以轻易地添加到任何已经存在的LayoutManager和Adapter上面! 它不会影响添加到item上的动画, 并且支持类别严格的"拖", 以及"放"时的动画, 还可以支持更多.
准备:
首先, 我们所需要的是添加RecyclerView的依赖:
compile 'com.android.support:recyclerview-v7:25.3.0'
使用ItemTouchHelper和ItemTouchHelper.Callback:
为了使用ItemTouchHelper, 你将创建一个ItemTouchHelper.Callback, 这是一个接口, 允许你监听"move"和"swipe"事件, 而且你可以通过Callback来控件已选中view的状态, 并且可以改变该view的默认动画. 如果只是想要一个基础实现, 你可以使用SimpleCallback这个帮助类, 但是为了学习Callback的工作原理, 我们将会自己实现一个.
为了激活基本的"拖放"和"滑动删除", 我们必须覆盖的主要方法是:
getMovementFlags(RecyclerView, ViewHolder) onMove(RecyclerView, ViewHolder, ViewHolder) onSwiped(ViewHolder, int)
我们也要使用这两个方法:
isLongPressDragEnabled() isItemViewSwipeEnabled()
我们一个一个地看一下:
@Override
public int getMovementFlags(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
ItemTouchHelper允许你轻易地决定事件的方向.你必须实现getMovementFlags(RecyclerView, RecyclerView.ViewHolder)方法来指明"拖"和"滑动"所支持的方向, 并且使用ItemTouchHelper.makeMovementFlags(int, int)来构建返回标签. 在此我们在两个不同的方向激活"拖"和"滑动".
@Override
public boolean isLongPressDragEnabled() {
return true;
}
ItemTouchHelper能够用来实现"没有滑动的拖动"或者"没有拖动的滑动", 所以你必须精确地指明想要支持的动作. 如果你想要在RecyclerView的item上支持"长按启动拖放"事件, 你就必须实现isLongPressDragEnabled()返回true. 此外, ItemTouchHelper.startDrag(RecyclerView.ViewHolder)可以从"操作"中启动"拖放", 这一点会在之后详述.
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
要想要view内部的任意触摸事件都可以启动"滑动"动作, 就简单地在isItemViewSwipeEnabled()返回true. 此外, ItemTouchHelper.startSwipe(RecyclerView.ViewHolder)能够手动地启动"滑动"事件.
然后, onMove()和onSwiped()方法需要实现, 来通知负责更新基础数据的东西. 所以, 首先, 我们要创建一个接口, 以允许我们传递"拖放"和"滑动删除"事件的回调.
public interface ItemTouchHelperAdapter {
void onItemMove(int fromPosition, int toPosition);
void onItemDismiss(int position);
}
从当前示例来讲, 要实现这些的最简单的方式, 是将我们的RecyclerView.Adapter实现这个接口:
public class RecyclerListAdapter extends
RecyclerView.Adapter<ItemViewHolder>
implements ItemTouchHelperAdapter {
// ... code from gist
@Override
public void onItemDismiss(int position) {
mItems.remove(position);
notifyItemRemoved(position);
}
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(mItems, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(mItems, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
return true;
}
调用notifyItemRemoved(int)和notifyItemMoved(int, int)是非常重要的, 由此, Adapter会更新数据. 请注意, 这也很重要, 我们改变item的position是在每一次view被切换到新的index, 而不是在"放"事件之后.
现在我们回来构建SimpleItemTouchHelperCallback, 因为我们依然必须覆盖onMove()和onSwiped()方法. 首先, 为Adapter添加构建器和变量:
private final ItemTouchHelperAdapter mAdapter;
public SimpleItemTouchHelperCallback(
ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
然后覆盖剩下的事件并通知Adapter:
@Override
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
mAdapter.onItemMove(viewHolder.getAdapterPosition(),
target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder,
int direction) {
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
这个Callback应该看起来像这样:
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final ItemTouchHelperAdapter mAdapter;
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder,
ViewHolder target) {
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(ViewHolder viewHolder, int direction) {
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
}
当Callback准备好之后, 我们创建ItemTouchHelper并调用attachToRecyclerView(RecyclerView)方法:
ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter); ItemTouchHelper touchHelper = new ItemTouchHelper(callback); touchHelper.attachToRecyclerView(recyclerView);
当你运行的时候, 结果应该看起来像这样:
总结
这是一个ItemTouchHelper极简单的实现. 但是我们应该清楚, 在RecyclerView上面实现基本的"拖放"和"滑动删除", 使用第三方和库是完全没有必要的.
示例代码请点击这里.
以上所述是小编给大家介绍的Android一步步带你在RecyclerView上面实现"拖放"和"滑动删除"功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# recyclerview
# 滑动
# 拖放
# android
# Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2
# android RecyclerView侧滑菜单
# 滑动删除
# 长按拖拽
# 下拉刷新上拉加载
# android RecyclerView实现条目Item拖拽排序与滑动删除
# Android中RecyclerView实现滑动删除与拖拽功能
# Android 滑动监听RecyclerView线性流+左右划删除+上下移动
# Android RecyclerView滑动删除和拖动排序
# Android RecyclerView实现滑动删除
# 是在
# 你可以
# 在此
# 这是一个
# 这两个
# 拖动
# 你必须
# 创建一个
# 小编
# 的是
# 是一个
# 还可以
# 你就
# 将会
# 子类
# 也要
# 你在
# 当你
# 会在
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
Laravel如何保护应用免受CSRF攻击?(原理和示例)
Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
轻松掌握MySQL函数中的last_insert_id()
香港服务器租用每月最低只需15元?
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
HTML 中动态设置元素 name 属性的正确语法详解
网站建设要注意的标准 促进网站用户好感度!
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
Laravel如何使用Telescope进行调试?(安装和使用教程)
如何在IIS中配置站点IP、端口及主机头?
Laravel怎么使用artisan命令缓存配置和视图
PHP正则匹配日期和时间(时间戳转换)的实例代码
*服务器网站为何频现安全漏洞?
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
中山网站推广排名,中山信息港登录入口?
详解Android中Activity的四大启动模式实验简述
悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】
Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
,在苏州找工作,上哪个网站比较好?
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
Linux后台任务运行方法_nohup与&使用技巧【技巧】
网站制作大概多少钱一个,做一个平台网站大概多少钱?
php做exe能调用系统命令吗_执行cmd指令实现方式【详解】
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
大型企业网站制作流程,做网站需要注册公司吗?
php json中文编码为null的解决办法
Python进程池调度策略_任务分发说明【指导】
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
网站优化排名时,需要考虑哪些问题呢?
Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
免费网站制作appp,免费制作app哪个平台好?
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】

