You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView侧滑交互优化:实现点击删除+左侧编辑按钮

实现RecyclerView侧滑显示编辑、删除按钮(点击触发操作)

我来帮你调整代码,实现侧滑只显示操作按钮、点击才执行删除/编辑的需求,具体分这几步来做:

一、修改SwipeToActionCallback类,支持双向侧滑并绘制按钮

首先我们要重构原来的回调类,让它支持左右双向侧滑,并且只绘制按钮不自动执行删除逻辑:

public abstract class SwipeToActionCallback extends ItemTouchHelper.Callback {
    private Context context;
    private Paint clearPaint;
    private ColorDrawable leftBackground; // 编辑按钮背景
    private ColorDrawable rightBackground; // 删除按钮背景
    private int editBgColor;
    private int deleteBgColor;
    private Drawable editDrawable;
    private Drawable deleteDrawable;
    private int intrinsicWidth;
    private int intrinsicHeight;

    public SwipeToActionCallback(Context context) {
        this.context = context;
        // 初始化编辑相关资源
        leftBackground = new ColorDrawable();
        editBgColor = Color.parseColor("#F4B400");
        editDrawable = ContextCompat.getDrawable(context, R.drawable.ic_edit_white_24dp);
        // 初始化删除相关资源
        rightBackground = new ColorDrawable();
        deleteBgColor = Color.parseColor("#DB3236");
        deleteDrawable = ContextCompat.getDrawable(context, R.drawable.ic_delete_white_24dp);

        clearPaint = new Paint();
        clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        if (editDrawable != null) {
            intrinsicWidth = editDrawable.getIntrinsicWidth();
            intrinsicHeight = editDrawable.getIntrinsicHeight();
        }
    }

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        // 支持左右双向侧滑
        return makeMovementFlags(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        return false;
    }

    // 移除自动删除逻辑,这个方法留空
    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {}

    @Override
    public void onChildDraw(@NonNull Canvas canvas, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        View itemView = viewHolder.itemView;
        int itemHeight = itemView.getHeight();
        boolean isCancelled = dX == 0 && !isCurrentlyActive;

        if (isCancelled) {
            clearCanvas(canvas, itemView.getLeft(), itemView.getTop(), itemView.getRight(), itemView.getBottom());
            super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            return;
        }

        // 根据侧滑方向绘制对应按钮
        if (dX < 0) {
            // 左滑:显示右侧删除按钮
            rightBackground.setColor(deleteBgColor);
            rightBackground.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
            rightBackground.draw(canvas);

            // 绘制删除图标
            int deleteIconTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2;
            int deleteIconMargin = (itemHeight - intrinsicHeight) / 2;
            int deleteIconLeft = itemView.getRight() - deleteIconMargin - intrinsicWidth;
            int deleteIconRight = itemView.getRight() - deleteIconMargin;
            int deleteIconBottom = deleteIconTop + intrinsicHeight;
            if (deleteDrawable != null) {
                deleteDrawable.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom);
                deleteDrawable.draw(canvas);
            }
        } else if (dX > 0) {
            // 右滑:显示左侧编辑按钮
            leftBackground.setColor(editBgColor);
            leftBackground.setBounds(itemView.getLeft(), itemView.getTop(), itemView.getLeft() + (int) dX, itemView.getBottom());
            leftBackground.draw(canvas);

            // 绘制编辑图标
            int editIconTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2;
            int editIconMargin = (itemHeight - intrinsicHeight) / 2;
            int editIconLeft = itemView.getLeft() + editIconMargin;
            int editIconRight = itemView.getLeft() + editIconMargin + intrinsicWidth;
            int editIconBottom = editIconTop + intrinsicHeight;
            if (editDrawable != null) {
                editDrawable.setBounds(editIconLeft, editIconTop, editIconRight, editIconBottom);
                editDrawable.draw(canvas);
            }
        }

        super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    private void clearCanvas(Canvas canvas, float left, float top, float right, float bottom) {
        canvas.drawRect(left, top, right, bottom, clearPaint);
    }

    // 降低侧滑阈值,让按钮更容易完全显示
    @Override
    public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) {
        return 0.3f;
    }

    // 定义回调接口,让外部处理点击事件
    public interface OnActionClickListener {
        void onEdit(int position);
        void onDelete(int position);
    }
}

二、给操作按钮添加点击事件

ItemTouchHelper仅负责绘制按钮,没有内置点击逻辑,我们需要通过RecyclerView的触摸监听来判断点击区域:

// 在你的Activity/Fragment中给RecyclerView添加触摸监听
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
    @Override
    public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        if (e.getAction() == MotionEvent.ACTION_UP) {
            View child = rv.findChildViewUnder(e.getX(), e.getY());
            if (child != null) {
                int position = rv.getChildAdapterPosition(child);
                RecyclerView.ViewHolder holder = rv.findViewHolderForAdapterPosition(position);
                if (holder != null) {
                    View itemView = holder.itemView;
                    float touchX = e.getX();

                    // 判断点击区域
                    if (touchX < itemView.getLeft() + intrinsicWidth + 40) {
                        // 点击了编辑按钮区域
                        actionClickListener.onEdit(position);
                        // 点击后恢复条目原始位置
                        new ItemTouchHelper(callback).startSwipe(holder);
                    } else if (touchX > itemView.getRight() - intrinsicWidth - 40) {
                        // 点击了删除按钮区域
                        actionClickListener.onDelete(position);
                        // 点击后恢复条目原始位置
                        new ItemTouchHelper(callback).startSwipe(holder);
                    }
                }
            }
        }
        return false;
    }

    @Override
    public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {}

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
});

三、在Adapter中处理编辑/删除逻辑

在你的RecyclerView Adapter中实现回调接口,处理具体的业务逻辑:

public class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {
    private List<YourData> dataList;
    private SwipeToActionCallback.OnActionClickListener actionClickListener;

    // 构造方法传入回调
    public YourAdapter(List<YourData> dataList, SwipeToActionCallback.OnActionClickListener listener) {
        this.dataList = dataList;
        this.actionClickListener = listener;
    }

    // ... 省略onCreateViewHolder、onBindViewHolder等基础方法

    public static class ViewHolder extends RecyclerView.ViewHolder {
        // 初始化你的条目组件
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }

    // 处理删除操作
    public void deleteItem(int position) {
        dataList.remove(position);
        notifyItemRemoved(position);
    }

    // 处理编辑操作
    public void editItem(int position) {
        YourData targetData = dataList.get(position);
        // 这里可以跳转到编辑界面或执行编辑逻辑
    }
}

四、初始化组件并绑定

最后在你的Activity/Fragment中完成初始化和绑定:

// 初始化侧滑回调
SwipeToActionCallback callback = new SwipeToActionCallback(this) {};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);

// 初始化Adapter并设置回调
SwipeToActionCallback.OnActionClickListener actionClickListener = new SwipeToActionCallback.OnActionClickListener() {
    @Override
    public void onEdit(int position) {
        adapter.editItem(position);
    }

    @Override
    public void onDelete(int position) {
        adapter.deleteItem(position);
    }
};

YourAdapter adapter = new YourAdapter(dataList, actionClickListener);
recyclerView.setAdapter(adapter);

这样修改后,你就能实现:右滑条目显示左侧编辑按钮,左滑显示右侧删除按钮,点击对应按钮才会执行编辑或删除操作,侧滑后不会自动删除条目啦。

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:39:09