主要借鉴这位博主写的博客,很详细仿微信朋友圈发表图片拖拽和删除功能_android 发布朋友圈拖动_天兰之珠的博客-CSDN博客
注意注意:自己的布局,需要滑动的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.ViewHolderviewHolder, @NonNull RecyclerView.ViewHolder target) {if (mDataList.size()<=0) {return false;}// 得到拖动ViewHolder的Positionint fromPosition = viewHolder.getAbsoluteAdapterPosition();// 得到目标ViewHolder的Positionint 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 RecyclerViewrecyclerView, @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) {//在删除处放手,则删除itemint absoluteAdapterPosition = viewHolder.getAbsoluteAdapterPosition();dragListener.deleteOk(absoluteAdapterPosition);initData();return;}} else {//没有到删除处dragListener.deleteState(false);}super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); }
如果自己需要进行别的操作可以在
DragListener接口中定义自己需要的接口,返回就是了,这里开放性好一些