Recyclerview单条拖拽ItemTouchHelper仿微信下拉小程序删除

本文介绍了如何在Android应用中实现类似微信朋友圈的图片拖拽和删除功能,重点讲解了`ItemTouchHelper`的使用,以及如何针对`GridLayoutManager`进行优化,确保只能在特定方向拖动和限制特定条件下交换位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要借鉴这位博主写的博客,很详细仿微信朋友圈发表图片拖拽和删除功能_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接口中定义自己需要的接口,返回就是了,这里开放性好一些
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn_zxw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值