如果打算爱一个人,你要想清楚,是否愿意为了他,放弃如上帝般自由的心灵,从此心甘情愿有了羁绊。——《了不起的盖茨比》

GitHub地址:SwipeDelMenuLayout

最近研究了一款非常轻量、易用的侧滑删除控件 SwipeDelMenuLayout,它与传统的 RecyclerView 或 ListView 的实现方式完全不同,完全不依赖任何特定的父布局,可以直接用在任意的 ViewGroup 中。这种设计让它的耦合性降到了零,无论你使用什么布局结构,都可以轻松集成侧滑删除功能。以下内容将详细介绍它的使用方法及其优势。


SwipeDelMenuLayout 是什么?

SwipeDelMenuLayout 是一个自定义 ViewGroup,用于实现像 iOS 一样的滑动删除菜单。它通过简单替换 Item 的根布局即可实现侧滑效果,而不需要对 RecyclerView 或 ListView 进行额外的侵入式改造。无论你的项目需求如何,只需引入这个控件,就能快速实现高效、平滑的侧滑交互。

关键点:

  • 不依赖特定父布局,可应用于任意 ViewGroup。
  • 完全解耦,无需修改现有的 Adapter 或数据结构。
  • 支持多指滑动屏蔽,避免多个菜单同时展开。
  • 提供 iOS 风格的“阻塞式交互”与 Android 风格的“非阻塞式交互”。

使用步骤

1. 添加依赖

首先,将 SwipeDelMenuLayout 添加到项目中。可以从 GitHub 下载源码:SwipeDelMenuLayout GitHub

或者直接将核心类文件 SwipeDelMenuLayout.java 拷贝到你的项目中,无需额外依赖。

2. 替换 Item 根布局

在你的 XML 布局中,将每个 Item 的根布局替换为 SwipeDelMenuLayout。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<com.mcxtzhang.swipedelmenu.SwipeDelMenuLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<!-- 左滑菜单部分 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@android:color/holo_red_light">
<TextView
android:layout_width="80dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="删除"
android:textColor="@android:color/white" />
</LinearLayout>

<!-- 内容部分 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这里是内容" />
</LinearLayout>
</com.mcxtzhang.swipedelmenu.SwipeDelMenuLayout>

这个布局中,SwipeDelMenuLayout 包裹了两个子布局,一个是左滑菜单(删除按钮),一个是内容区域。

3. 配置 Adapter(如果使用 RecyclerView)

在 Adapter 的 onBindViewHolder 方法中,只需要正常绑定数据,无需额外处理。SwipeDelMenuLayout 会自动管理滑动逻辑和手势冲突。


两种滑动模式

SwipeDelMenuLayout 提供两种滑动交互模式:

  1. 非阻塞模式(Android 风格)

    • 打开一个菜单时,可以直接滑动其他 Item,无需关闭当前菜单。
    • 自动关闭上一个已打开的菜单。
    • 适合更自由的交互需求。
  2. 阻塞模式(iOS 风格)

    • 打开一个菜单后,必须先关闭当前菜单才能操作其他 Item。
    • 更贴近 iOS 的交互逻辑,符合某些产品的定制化需求。

可以根据项目需求,自行选择合适的交互模式。


核心实现原理

  1. 静态变量管理菜单状态
    为了避免多个菜单同时打开,控件内部使用了静态变量记录当前激活的 SwipeDelMenuLayout,在每次打开或关闭菜单时,都会先检测并处理已打开的菜单。

  2. 属性动画与平滑滚动
    提供了属性动画(平滑滚动)和 Scroller(精确滑动)两种实现方式,开发者可以根据需求切换动画效果。

  3. 事件分发与手势冲突处理
    自定义 ViewGroup 内部对 onInterceptTouchEventonTouchEvent 进行了细致的处理,屏蔽了多指滑动冲突,保证滑动操作的流畅性和唯一性。


效果预览

  1. 非阻塞模式

    • 可以随意滑动任何 Item,已打开的菜单会自动关闭。
  2. 阻塞模式

    • 打开菜单后无法滑动其他 Item,需先关闭菜单。

使用场景

  • 适用于所有 ViewGroup 中的侧滑操作,比如 LinearLayout、FrameLayout 等。
  • 特别适合需要自定义布局的复杂场景,例如混合使用 RecyclerView 和静态布局。

SwipeDelMenuLayout 是一个简单高效的解决方案,完全摆脱了对特定父布局的依赖,既解放了开发者,也提升了代码的复用性。无论是构建小型项目还是复杂的多模块应用,它都可以轻松集成。如果你也对 Android 的侧滑删除感兴趣,不妨试试这个工具!