热门
需要实现拖拽的功能如下所示
几个重要的方法说明
isLongPressDragEnabled 是否可以长按拖拽排序 isItemViewSwipeEnabled Item是否可以被滑动 getMovementFlags 当用户拖拽或者滑动Item的时候需要我们告诉系统滑动或者拖拽的方向 onMove 当Item被拖拽的时候被回调 onSwiped 当View被滑动删除的时候 onSelectedChanged 当item被拖拽或侧滑时触发
几个方法中代码思路
上下拖动时与其他item进行位置交换
左右滑出屏幕时其他item补上
拖拽效果优化
完整代码如下所示
/** * <pre> * @author 杨充 * blog : https://github.com/yangchong211 * time : 2017/5/2 * desc : 自定义ItemTouchHelper * revise: 参考严正杰大神博客:https://blog.csdn.net/yanzhenjie1003/article/details/51935982 * </pre> */ public class ItemTouchHelpCallback extends ItemTouchHelper.Callback { /** * Item操作的回调,去更新UI和数据源 */ private OnItemTouchCallbackListener onItemTouchCallbackListener; /** * 是否可以拖拽 */ private boolean isCanDrag = false; /** * 是否可以被滑动 */ private boolean isCanSwipe = false; /** * 按住拖动item的颜色 */ private int color = 0; public ItemTouchHelpCallback(OnItemTouchCallbackListener onItemTouchCallbackListener) { this.onItemTouchCallbackListener = onItemTouchCallbackListener; } /** * 设置是否可以被拖拽 * * @param canDrag 是true,否false */ public void setDragEnable(boolean canDrag) { isCanDrag = canDrag; } /** * 设置是否可以被滑动 * * @param canSwipe 是true,否false */ public void setSwipeEnable(boolean canSwipe) { isCanSwipe = canSwipe; } /** * 设置按住拖动item的颜色 * @param color 颜色 */ public void setColor(@ColorInt int color){ this.color = color; } /** * 当Item被长按的时候是否可以被拖拽 * * @return true */ @Override public boolean isLongPressDragEnabled() { return isCanDrag; } /** * Item是否可以被滑动(H:左右滑动,V:上下滑动) * isItemViewSwipeEnabled()返回值是否可以拖拽排序,true可以,false不可以 * @return true */ @Override public boolean isItemViewSwipeEnabled() { return isCanSwipe; } /** * 当用户拖拽或者滑动Item的时候需要我们告诉系统滑动或者拖拽的方向 * 动作标识分:dragFlags和swipeFlags * dragFlags:列表滚动方向的动作标识(如竖直列表就是上和下,水平列表就是左和右) * wipeFlags:与列表滚动方向垂直的动作标识(如竖直列表就是左和右,水平列表就是上和下) * * 思路:如果你不想上下拖动,可以将 dragFlags = 0 * 如果你不想左右滑动,可以将 swipeFlags = 0 * 最终的动作标识(flags)必须要用makeMovementFlags()方法生成 */ @Override public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { // flag如果值是0,相当于这个功能被关闭 int dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlag = 0; // create make return makeMovementFlags(dragFlag, swipeFlag); } else if (layoutManager instanceof LinearLayoutManager) { LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager; int orientation = linearLayoutManager.getOrientation(); int dragFlag = 0; int swipeFlag = 0; // 为了方便理解,相当于分为横着的ListView和竖着的ListView // 如果是横向的布局 if (orientation == LinearLayoutManager.HORIZONTAL) { swipeFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN; dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; } else if (orientation == LinearLayoutManager.VERTICAL) { // 如果是竖向的布局,相当于ListView dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN; swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; } //第一个参数是拖拽flag,第二个是滑动的flag return makeMovementFlags(dragFlag, swipeFlag); } return 0; } /** * 当Item被拖拽的时候被回调 * * @param recyclerView recyclerView * @param srcViewHolder 当前被拖拽的item的viewHolder * @param targetViewHolder 当前被拖拽的item下方的另一个item的viewHolder * @return 是否被移动 */ @Override public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder srcViewHolder, @NonNull RecyclerView.ViewHolder targetViewHolder) { if (onItemTouchCallbackListener != null) { int srcPosition = srcViewHolder.getAdapterPosition(); int targetPosition = targetViewHolder.getAdapterPosition(); return onItemTouchCallbackListener.onMove(srcPosition, targetPosition); } return false; } /** * 当item侧滑出去时触发(竖直列表是侧滑,水平列表是竖滑) * * @param viewHolder viewHolder * @param direction 滑动的方向 */ @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { if (onItemTouchCallbackListener != null) { onItemTouchCallbackListener.onSwiped(viewHolder.getAdapterPosition()); } } /** * 当item被拖拽或侧滑时触发 * * @param viewHolder viewHolder * @param actionState 当前item的状态 */ @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); //不管是拖拽或是侧滑,背景色都要变化 if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { if (color==0){ viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext() .getResources().getColor(android.R.color.darker_gray)); }else { viewHolder.itemView.setBackgroundColor(color); } } } /** * 当item的交互动画结束时触发 * * @param recyclerView recyclerView * @param viewHolder viewHolder */ @Override public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources() .getColor(android.R.color.white)); viewHolder.itemView.setAlpha(1); viewHolder.itemView.setScaleY(1); } @Override public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { float value = 1 - Math.abs(dX) / viewHolder.itemView.getWidth(); viewHolder.itemView.setAlpha(value); viewHolder.itemView.setScaleY(value); } } public interface OnItemTouchCallbackListener { /** * 当某个Item被滑动删除的时候 * * @param adapterPosition item的position */ void onSwiped(int adapterPosition); /** * 当两个Item位置互换的时候被回调 * * @param srcPosition 拖拽的item的position * @param targetPosition 目的地的Item的position * @return 开发者处理了操作应该返回true,开发者没有处理就返回false */ boolean onMove(int srcPosition, int targetPosition); } }
如何使用,代码如下所示
ItemTouchHelpCallback callback = new ItemTouchHelpCallback((srcPosition, targetPosition) -> { if (imageBeans != null) { try { // 更换数据源中的数据Item的位置。更改list中开始和结尾position的位置 Collections.swap(imageBeans, srcPosition, targetPosition); // 更新UI中的Item的位置,主要是给用户看到交互效果 mAdapter.notifyItemMoved(srcPosition, targetPosition); } catch (Exception e){ e.printStackTrace(); } return true; } return true; }); callback.setDragEnable(true); callback.setSwipeEnable(true); callback.setColor(this.getResources().getColor(R.color.base_background_block)); //创建helper对象,callback监听recyclerView item 的各种状态 ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback); try{ //关联recyclerView,一个helper对象只能对应一个recyclerView itemTouchHelper.attachToRecyclerView(recyclerView); }catch (Exception e){ e.printStackTrace(); }
00.RecyclerView复杂封装库
01.RecyclerView
02.Adapter
03.ViewHolder
04.LayoutManager
05.SnapHelper
07.SpanSizeLookup
08.ItemDecoration
09.RecycledViewPool
11.RecyclerView上拉加载
12.RecyclerView缓存原理
13.SnapHelper源码分析
16.自定义SnapHelper
19.自定义ItemDecoration分割线
22.RecyclerView问题汇总
23.RecyclerView滑动冲突
24.ScrollView嵌套RecyclerView问题