主要借鉴这位博主写的博客,很详细仿微信朋友圈发表图片拖拽和删除功能_android 发布朋友圈拖动_天兰之珠的博客-优快云博客
注意注意:自己的布局,需要滑动的Recyclerview的父布局一定要是全屏的,可以自己摸索一下就知道需要全局了
主要做了点优化
ItemTouchHelperCallback中对GridLayoutManager修改,这里需要根据用的Manager进行判断
@Override public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { //判断 recyclerView的布局管理器数据,设置 item 只能处理拖拽事件,并能够向左、右、上、下拖拽 if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {//设置能拖拽的方向 dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; swipeFlags = 0;//0则不响应滑动事件 } return makeMovementFlags(dragFlags, swipeFlags); }
在onMove中对加号进行判断,如果是自己本地的图片的时候是不能进行互换位置的,这里的判断可以根据自己的情况进行相关的判断,不一定按照我这个来
/** * 拖拽,交换位置(当用户从item原来的位置拖动可以拖动的item到新位置的过程中调用) * * @param viewHolder 拖动的 item * @param target 目标 item */ @Override public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { if (mDataList.size()<=0) { return false; } // 得到拖动ViewHolder的Position int fromPosition = viewHolder.getAbsoluteAdapterPosition(); // 得到目标ViewHolder的Position int toPosition = target.getAbsoluteAdapterPosition(); //如果是加号的时候不可以互换 这里判断可以根据自己情况判断 if(TAG.equals(mDataList.get(fromPosition).getType())||TAG.equals(mDataList.get(toPosition).getType())){ return false; } if (fromPosition < toPosition) {//顺序小到大 for (int i = fromPosition; i < toPosition; i++) { Collections.swap(mDataList, i, i + 1); } } else {//顺序大到小 for (int i = fromPosition; i > toPosition; i--) { Collections.swap(mDataList, i, i - 1); } } mAdapter.notifyItemMoved(fromPosition, toPosition); dragListener.itemMove(fromPosition, toPosition); return true; }
onChildDraw中对控件距离底部的距离自己需要重新计算,毕竟每个需求不一定一样,所以
if (dY >= mScrollView.getHeight() - viewHolder.itemView.getBottom()-recyclerView.getY() - deleteViewHeight + mScrollView.getScrollY())这个判断条件需要根据自己的需要进行优化
我这里有两个Recyclerview都会进行删除操作,这里不仅需要viewHolder.itemView.getBottom()判断控件距离Recyclerview的顶部距离,也需要当前Recyclerview距离总布局顶部的距离,其余的都好理解了,如果删除就调用接口返回就是了
/** * 自定义拖动与滑动交互 * * @param c * @param recyclerView * @param viewHolder * @param dX X轴移动的距离 * @param dY Y轴移动的距离 * @param actionState 当前Item的状态 * @param isCurrentlyActive 如果当前被用户操作为true,反之为false */ @Override public void onChildDraw(Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { if (null == dragListener) { return; } //删除区间的高度 int deleteViewHeight = SizeUtils.dp2px(60); //viewHolder.itemView.getBottom() item底部距离recyclerView顶部高度 //recyclerview 距离顶部距离 recyclerView.getY() if (dY >= (mScrollView.getHeight()) - viewHolder.itemView.getBottom()-recyclerView.getY() - deleteViewHeight + mScrollView.getScrollY()) {//拖到删除处 dragListener.deleteState(true); if (up) {//在删除处放手,则删除item int absoluteAdapterPosition = viewHolder.getAbsoluteAdapterPosition(); dragListener.deleteOk(absoluteAdapterPosition); initData(); return; } } else {//没有到删除处 dragListener.deleteState(false); } super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); }
如果自己需要进行别的操作可以在
DragListener接口中定义自己需要的接口,返回就是了,这里开放性好一些