效果图如下:

代码1:具体核心代码:

private ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {@Overridepublic int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {//设置监听拖拽的方向int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;int swipeFlags = 0; return makeMovementFlags(dragFlags, swipeFlags);}@Overridepublic boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {int fromPosition = viewHolder.getAdapterPosition();//得到item原来的positionint toPosition = target.getAdapterPosition();//得到目标positionif ((toPosition == listImgData.size() - 1 || listImgData.size() - 1 == fromPosition) && TextUtils.equals(listImgData.get(listImgData.size() - 1), "add")) {return true;}//滑动事件Collections.swap(listImgData, viewHolder.getAdapterPosition(), target.getAdapterPosition());mAdapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());return false;}@Overridepublic void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {}@Overridepublic boolean isLongPressDragEnabled() {//是否可拖拽return false;}@Overridepublic void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {super.onSelectedChanged(viewHolder, actionState);if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {viewHolder.itemView.setScaleX(1.1f);viewHolder.itemView.setScaleY(1.1f);}}@Overridepublic void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {super.clearView(recyclerView, viewHolder);if (!recyclerView.isComputingLayout()) {//拖拽结束后恢复view的状态viewHolder.itemView.setScaleX(1.0f);viewHolder.itemView.setScaleY(1.0f);}}});

这里是否可以拖拽都是靠 isLongPressDragEnabled  这个回调设置的,如果设置fase是不能拖拽的,由于我这里最后一个是不能进行拖拽的,但是设置false就全部不能进行拖拽了,我们的需要的效果就是其他可以拖拽,最后一个或者特定字符的不需要拖拽

先查看源码,发现这里使用了isLongPressDragEnabled

 private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {ItemTouchHelperGestureListener() {}@Overridepublic boolean onDown(MotionEvent e) {return true;}@Overridepublic void onLongPress(MotionEvent e) {View child = findChildView(e);if (child != null) {ViewHolder vh = mRecyclerView.getChildViewHolder(child);if (vh != null) {if (!mCallback.hasDragFlag(mRecyclerView, vh)) {return;}int pointerId = e.getPointerId(0);// Long press is deferred.// Check w/ active pointer id to avoid selecting after motion// event is canceled.if (pointerId == mActivePointerId) {final int index = e.findPointerIndex(mActivePointerId);final float x = e.getX(index);final float y = e.getY(index);mInitialTouchX = x;mInitialTouchY = y;mDx = mDy = 0f;if (DEBUG) {Log.d(TAG,"onlong press: x:" + mInitialTouchX + ",y:" + mInitialTouchY);}if (mCallback.isLongPressDragEnabled()) {select(vh, ACTION_STATE_DRAG);}}}}}}

上面源码ItemTouchHelperGestureListener是手指拖拽的一个监听

如果长按的时候isLongPressDragEnabled  返回false  ,控件就不会出现拖拽

上面代码用于监听触摸手势

触摸手势的触摸监听又由下面代码传入触摸事件

最开始的触摸事件监听是RecyclerView的

由此可见,重新自定义一个触摸手势长按事件可满足我们的需求

想法:需要拖拽执行就必须执行   select(vh, ACTION_STATE_DRAG);  这个方法

看了看源码,尴尬,这个方法不能外部调用的,反正这个方法就是长按的时候可以让你拖拽

继续查看刚刚的按个是否可以长按拖拽,发现旁边有个  startDrag 的方法,

   /*** Returns whether ItemTouchHelper should start a drag and drop operation if an item is* long pressed.* <p>* Default value returns true but you may want to disable this if you want to start* dragging on a custom view touch using {@link #startDrag(ViewHolder)}.** @return True if ItemTouchHelper should start dragging an item when it is long pressed,* false otherwise. Default value is <code>true</code>.* @see #startDrag(ViewHolder)*/public boolean isLongPressDragEnabled() {return true;}

发现startDrag 里面也是执行了 select(vh, ACTION_STATE_DRAG);   这个进行开始拖拽的

代码2:自定义手势触摸代码:

public abstract class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener {private GestureDetectorCompat mGestureDetector;private RecyclerView recyclerView;public OnRecyclerItemClickListener(RecyclerView recyclerView) {this.recyclerView = recyclerView;mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener());}@Overridepublic boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {mGestureDetector.onTouchEvent(e);return false;}@Overridepublic void onTouchEvent(RecyclerView rv, MotionEvent e) {mGestureDetector.onTouchEvent(e);}@Overridepublic void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {@Overridepublic boolean onSingleTapUp(MotionEvent e) {View child = recyclerView.findChildViewUnder(e.getX(), e.getY());if (child != null) {RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);onItemClick(vh);}return true;}@Overridepublic void onLongPress(MotionEvent e) {View child = recyclerView.findChildViewUnder(e.getX(), e.getY());if (child != null) {RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);onItemLongClick(vh);}}}public abstract void onItemClick(RecyclerView.ViewHolder vh);public abstract void onItemLongClick(RecyclerView.ViewHolder vh);}

代码3:设置监听,mRecyclerView是你项目里面的,设置好图片就可以添加下面的监听

helper.attachToRecyclerView(mRecyclerView);
mRecyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(mRecyclerView) {@Overridepublic void onItemClick(RecyclerView.ViewHolder vh) {}@Overridepublic void onItemLongClick(RecyclerView.ViewHolder vh) {//如果item不是最后一个,则执行拖拽if (vh.getLayoutPosition() != listImgData.size() - 1) {helper.startDrag(vh);} else if (!TextUtils.equals(listImgData.get(listImgData.size() - 1), "add")) {helper.startDrag(vh);}}});

上面就是大体代码了

Android 个人相册图片拖拽排序相关推荐

  1. JS的平凡之路--简易的图片拖拽排序

    由HTML5的拖放API,实现的简易图片拖放效果. 一.HTML5拖放API的知识点   首先我们得知道元素怎么才可以被拖放,需要设置它们的draggable属性,其中img和a标签的dragable ...

  2. antd vue3 图片上传组件扩展,支持多图上传 图片拖拽排序等

    组件涉及到 vue3.2.vite.Ant Design Vue 3.2.16.Windi CSS样式库.vuedraggable-es拖拽库等 组件功能 图片拖拽 多图上传 自定义图片加载样式 自定 ...

  3. 手机端适用:图片拖拽排序v-dragging

    为了不想用jquery,终于找到能兼容vue的插件,很好使 1.安装 npm install awe-dnd --save 2.main.js引入 import VueDND from 'awe-dn ...

  4. Android表格拖拽排序,Android 拖拽排序控件 DragGridView

    Android 拖拽排序控件 DragGridView Android 开发中,我们经常会遇到条目拖拽排序的需求,特别是在新闻类应用中就更普遍了.其实,我们在网上可以搜到许多关于拖拽排序的自定义控件, ...

  5. Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

  6. android可拖拽九宫格,微信小程序实现九宫格图片拖拽

    (在真机上的效果就不演示了,是差不多的) 实现思路 布局 在这里运用到了微信小程序的moveable-area和moveable-view两个标签. moveable-area是可拖拽的区域,需要设置 ...

  7. 拖拽删除元素、拖拽排序、拖拽预览图片和拖拽移动元素

    介绍 HTML5 提供了专门的拖拽与拖放的 API,目前各浏览器都已支持,包括 IE.HTML 拖放(Drag and Drop)接口使应用程序能够在浏览器中使用拖放功能.例如,用户可使用鼠标选择可拖 ...

  8. Android拖拽排序控件DragGridView

    Android开发中,我们经常会遇到条目拖拽排序的需求,特别是在新闻类应用中就更普遍了.其实,我们在网上可以搜到许多关于拖拽排序的自定义控件,今天,为大家介绍的是一个拖拽排序库DragGridView ...

  9. android gridview拖动排序,Asp.net GridView 拖拽排序    原创(欢迎拍砖,敬请嘴下留情!)...

    原理:客户端排序(或者说组织新的排序顺序),Ajax 更新服务器端数据. 客户端用jquery插件sortable实现拖拽排序,保存之前检索顺序变化了的数据,并组织成Json数据,用AJax传送到服务 ...

最新文章

  1. BeanUtils威力和代价
  2. org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'xx' is defined
  3. 上传问题分析2--文件重名
  4. MongoDB 凉了?
  5. java正则替换数字_Java 正则表达式,替换图片名称,替换数字,和谐用语,复制文件...
  6. LightOJ1245 Harmonic Number (II) —— 规律
  7. 题解 【NOIP2010】关押罪犯
  8. 测试方法-等价类划分法
  9. CAN 通信协议文档集锦
  10. 如何读群晖硬盘_群晖直接读取Windows硬盘-eSATA挂载
  11. 浅学一维傅里叶变换【下一章发布 : 快速二维傅里叶变换FFT、快速二维傅里叶逆变换IFFT】
  12. U盘中毒,文件夹或文件打不开的解决方法--实用
  13. 智能手表音频特性测试_TicWatch Pro 3 体验:智能手表的集大成者
  14. MySQL 8.0 高可用之如何解决从库数据被修改引起的主从同步错误
  15. Friedman 检验后的two-tailed Nemenyi test和the two-tailed Bonferroni-Dunn test的关键值
  16. 【Debug】OpenCV_Python:imshow() error “TypeError: Required argument 'mat' (pos 2) not found”
  17. 怎样用ocr软件识别图片中的文字
  18. 机箱前置音频插口没声音的解决
  19. HLSL中mul函数的使用
  20. 连连看逆向分析与外挂编写

热门文章

  1. 2023元宇宙趋势一:VR/AR推动互联网3D化
  2. 快速消费品的区域配送中心(RDC)运作的优化管理方法(zt)
  3. 29.html的iconfont(图标字体)
  4. linux usb 重启电脑,技术|如何在 Linux 中创建 USB 启动盘来拯救 Windows 用户
  5. 2024届毕业生的刷题记录
  6. joomla之T3框架使用教程1----安装
  7. 我观察14年才发现,那些很努力却没成就的人都有一个特点
  8. 扎根教育净土 共育教育之花
  9. 中文免费论文地址集锦 -论文参考
  10. 毕老师JAVA基础视频 学习日志——Java开发前奏