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

Android RecyclerView实现左右滑动删除/归档(分色显示)的方法

实现RecyclerView左右滑不同效果(左删右归档)的方案

嘿,我之前也折腾过一模一样的需求!用你现有的ItemTouchHelper完全能搞定双方向滑动的不同视觉和功能效果,不用换别的框架,咱们直接改代码就行,步骤很清晰:

1. 开启双向滑动权限

首先修改ItemTouchHelper.SimpleCallback的构造参数,把滑动方向从单一的LEFT改成LEFT | RIGHT,这样就允许左右两个方向的滑动了:

ItemTouchHelper.SimpleCallback swipeCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
    // 后续方法重写...
};

(第一个参数是拖拽方向,不需要的话传0就行)

2. 在onSwiped中区分方向处理业务逻辑

滑动结束后,根据不同的方向执行删除或归档操作:

@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
    int position = viewHolder.getAdapterPosition();
    if (direction == ItemTouchHelper.LEFT) {
        // 左滑:执行删除逻辑
        yourAdapter.removeItem(position);
    } else if (direction == ItemTouchHelper.RIGHT) {
        // 右滑:执行归档逻辑
        yourAdapter.archiveItem(position);
    }
}

3. 核心:在onChildDraw中绘制不同方向的背景和图标

这一步是实现视觉差异化的关键,我们要根据滑动的偏移量dX判断方向(dX>0是右滑,dX<0是左滑),然后分别绘制对应的背景色和图标:

首先提前初始化好需要的画笔和图标:

// 初始化背景画笔
Paint deleteBgPaint = new Paint();
deleteBgPaint.setColor(ContextCompat.getColor(context, R.color.swipe_delete_red));
deleteBgPaint.setStyle(Paint.Style.FILL);

Paint archiveBgPaint = new Paint();
archiveBgPaint.setColor(ContextCompat.getColor(context, R.color.swipe_archive_blue));
archiveBgPaint.setStyle(Paint.Style.FILL);

// 初始化图标
Drawable deleteIcon = ContextCompat.getDrawable(context, R.drawable.ic_delete_outline);
Drawable archiveIcon = ContextCompat.getDrawable(context, R.drawable.ic_archive_outline);

然后重写onChildDraw方法:

@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
    View itemView = viewHolder.itemView;
    int iconSize = deleteIcon.getIntrinsicHeight();
    int iconMargin = (itemView.getHeight() - iconSize) / 2; // 让图标垂直居中

    if (dX > 0) {
        // 右滑:绘制归档背景和图标
        // 绘制背景矩形:从item左边缘到滑动偏移位置
        c.drawRect(
            itemView.getLeft(),
            itemView.getTop(),
            itemView.getLeft() + dX,
            itemView.getBottom(),
            archiveBgPaint
        );
        // 设置图标位置:左边缘+边距,垂直居中
        archiveIcon.setBounds(
            itemView.getLeft() + iconMargin,
            itemView.getTop() + iconMargin,
            itemView.getLeft() + iconMargin + iconSize,
            itemView.getBottom() - iconMargin
        );
        archiveIcon.draw(c);
    } else if (dX < 0) {
        // 左滑:绘制删除背景和图标
        // 绘制背景矩形:从滑动偏移位置到item右边缘
        c.drawRect(
            itemView.getRight() + dX,
            itemView.getTop(),
            itemView.getRight(),
            itemView.getBottom(),
            deleteBgPaint
        );
        // 设置图标位置:右边缘-边距-图标宽度,垂直居中
        deleteIcon.setBounds(
            itemView.getRight() - iconMargin - iconSize,
            itemView.getTop() + iconMargin,
            itemView.getRight() - iconMargin,
            itemView.getBottom() - iconMargin
        );
        deleteIcon.draw(c);
    }

    // 必须调用父类方法,保证item的滑动动画正常执行
    super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}

额外注意事项

  • 如果你之前用了前景+背景的XML布局,现在可以去掉背景布局了,因为我们直接通过Canvas绘制背景,更灵活高效。
  • 如果你的item有圆角,可以用Path来绘制带圆角的背景矩形,避免和item形状冲突。
  • 图标建议用矢量图(VectorDrawable),保证不同分辨率下显示清晰。

这样改完之后,就能实现和Google Inbox类似的左右滑不同效果啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:26:47