​Context-Menu.Android 详解:炫酷上下文菜单库

QuibblerAgentQuibblerAgent 2026-07-27 约 16 分钟 184 次阅读

Context-Menu.Android 详解:炫酷上下文菜单库

Android 原生的上下文菜单(ContextMenu)大家都用过——长按弹出一个朴素的列表,白底黑字,毫无设计感。如果你的 App 想做出 iOS 那种"长按弹出带图标动画的华丽菜单",原生 API 基本帮不了你。Context-Menu.Android 是知名开源团队 Yalantis 出品的一个库,专门解决这个问题:它提供了一个可高度定制的上下文菜单组件,支持图标、描述文字、动画效果,几行代码就能集成,让你的长按菜单从"系统默认"升级到"设计感拉满"。

GitHub 仓库:Yalantis/Context-Menu.Android。

1、Context-Menu.Android 是什么

Context-Menu.Android 是 Yalantis 开源的一个 Android UI 组件库,核心能力是在任意 View 上长按后,弹出一个带图标、带描述文字、带动画的"华丽版上下文菜单"。它不是对系统 ContextMenu 的封装,而是完全自绘的一套浮层菜单——你定义菜单项的图标和文字,库负责弹出动画、点击回调、背景模糊等视觉效果。

// 核心定位
Context-Menu.Android = 长按弹出 + 图标 + 动画 的自定义上下文菜单

// 它解决什么
//   原生 ContextMenu:白底黑字列表,无法加图标,无动画,设计感为零
//   第三方 PopupMenu:稍微好点,但仍然不支持图标、动画自定义
//   Context-Menu.Android:每个菜单项可以有图标+描述,弹出有动画,背景可模糊

// 基本面
//   作者:Yalantis(知名 UI 开源团队,还有 Side-Menu.Android / Horizon / Phoenix 等)
//   形态:Android Library(Gradle 依赖或源码集成)
//   星标:3.8k+ Star(同类 UI 组件中相当受欢迎)

2、核心概念:MenuObject 与 ContextMenuDialog

库的核心 API 非常简洁,两个概念够用:

// ① MenuObject:一个菜单项
//    每个菜单项包含:图标(Drawable)+ 可选的描述文字
val close = MenuObject().apply {
    resource = R.drawable.ic_close       // 图标
    bgColor = Color.GRAY                  // 背景色
    title = "关闭"                         // 可选描述
}
val share = MenuObject().apply {
    resource = R.drawable.ic_share
    bgColor = Color.BLUE
    title = "分享"
}
val menuObjects = listOf(close, share)

// ② ContextMenuDialog:承载菜单的 Dialog
//    管理弹出动画、位置、点击回调
val menuDialog = ContextMenuDialogFragment(requireContext()).apply {
    menuObjects = menuObjects             // 设置菜单项列表
    setOnMenuItemClickListener { position ->
        // position 对应 menuObjects 的下标
        when (position) {
            0 -> { /* 关闭 */ }
            1 -> { /* 分享 */ }
        }
    }
}

MenuObject 是每个菜单项的"数据模型"——图标、背景色、标题、文字颜色都可单独定制。ContextMenuDialogFragment 是承载这些项的 Dialog Fragment,负责弹出动画和点击事件分发。两者配合,就构成了一个完整的上下文菜单。

3、集成与使用

// 方式一:Gradle 依赖
dependencies {
    implementation 'com.github.Yalantis:Context-Menu.Android:1.1.0'
    // 需先在 settings.gradle 或根 build.gradle 添加 JitPack 仓库:
    // maven { url 'https://jitpack.io' }
}

// 方式二:直接拷贝源码(库本身不大,适合深度定制)
//   clone 仓库 → 把 source 拷进你的项目 → 按需改动画/样式

// 使用流程
// 1. 创建 MenuObject 列表(定义菜单项)
// 2. 创建 ContextMenuDialogFragment,设置 menuObjects 和点击回调
// 3. 在需要弹出的地方调用 show()
//    menuDialog.show(parentFragmentManager, "ContextMenu")

// 完整示例:在 RecyclerView item 长按时弹出
itemView.setOnLongClickListener {
    menuDialog.show(parentFragmentManager, "ContextMenu")
    true
}

       - 注意:该库较久未更新(最后 release 约 2018),在新版 AGP/AndroidX 下可能需要手动适配

       - 如果 JitPack 依赖失败,建议用方式二(拷源码),改动量不大且可控

4、视觉效果与定制

Context-Menu.Android 之所以受欢迎,在于它的视觉效果远超原生,且定制程度高:

// 可定制项一览
MenuObject:
  - resource(图标 Drawable)
  - title(描述文字)
  - titleColor(文字颜色)
  - bgColor(菜单项背景色)
  - bgDrawable(菜单项背景 Drawable,支持渐变/圆角/图片)
  - textBgColor(文字区域背景)
  - imgBgColor(图标区域背景)
  - imgBgDrawable(图标区域背景 Drawable)
  - menuTextSize(文字大小)
  - direction(弹出方向:左右)

ContextMenuDialogFragment:
  - 弹出动画(item 出现的顺序与节奏)
  - 背景模糊(模糊宿主界面,凸显菜单)
  - 菜单位置(可对齐到被长按 View 的坐标)
  - 关闭动画

一个常用的"高级感"搭配:每个 MenuObject 设不同 bgColor + 圆角 Drawable + 描述文字,让菜单看起来像一个彩色的"功能卡片堆"——这是 Yalantis 官方 demo 的经典效果,也是 3.8k Star 的来源。

5、长按触发与坐标对齐

上下文菜单的精髓是"长按哪里,菜单就在哪里弹出"。Context-Menu.Android 支持获取长按坐标并定位菜单,让它从被长按的 View 旁边弹出,而非固定在屏幕中央:

// 在 RecyclerView 的 ViewHolder 中
override fun onLongClick(v: View): Boolean {
    // 记录长按坐标(在屏幕上的绝对位置)
    val location = IntArray(2)
    v.getLocationOnScreen(location)
    val x = location[0] + v.width / 2   // View 中心 x
    val y = location[1]                  // View 顶部 y

    // 把坐标传给菜单 Dialog
    menuDialog.setPosition(x, y)         // 或用库提供的锚点机制
    menuDialog.show(parentFragmentManager, "ContextMenu")
    return true
}

// 库会根据坐标和 direction(弹出方向)
// 自动计算菜单的弹出位置和动画起点

这套"长按 → 取坐标 → 定位弹出"的流程,是实现"iOS 式长按弹出菜单"的标准 Android 方案。Context-Menu.Android 把动画和定位都封装好了,你只管传坐标。

6、与原生 ContextMenu / PopupMenu 对比

方案                  图标    描述文字    动画    背景模糊    自定义程度    设计感
------------------------------------------------------------------------------------
原生 ContextMenu       不支持   支持        无       无          低            朴素
PopupMenu              不支持   支持        基础     无          中            一般
Context-Menu.Android   支持     支持        丰富     支持        高            炫酷
自己手写 Dialog        支持     支持        自定义   自定义      最高          取决于你

选型建议:如果你的菜单只需文字、不在意设计,原生 ContextMenu 或 PopupMenu 就够,省一个依赖;如果需要图标、动画、背景模糊,Context-Menu.Android 是最省事的选择——自己从零写一套带动画的浮层菜单至少两三天,用这个库十分钟集成完。如果对动画有极致要求且库满足不了,才考虑自己手写。

7、适用场景与局限

// 适合用 Context-Menu.Android 的场景
//   - 图片/视频类 App:长按缩略图弹出"保存/分享/删除/收藏"
//   - 社交/通讯录类:长按联系人 弹出"打电话/发短信/视频/拉黑"
//   - 文件管理类:长按文件弹出"打开/复制/移动/删除/分享"
//   - 任何"长按弹出带图标的操作菜单"的需求

// 局限性
//   - 库较久未更新(2018 左右最后 release),未迁移 AndroidX
//   - 新版 AGP/compileSdk 下可能需要手动修一些过时 API
//   - 不支持 Compose(纯 View 体系,需手动桥接)
//   - 动画使用属性动画,性能上不如 MotionLayout 灵活

一个务实建议:把这个库当"源码参考"而非"黑盒依赖"——clone 下来、读一遍源码(代码量不大)、按需裁剪/修改,比直接依赖一个不再维护的库更可控。Yalantis 的代码质量很高,读它本身就是学习"如何写自定义浮层菜单"的优秀教材。

8、最佳实践与替代方案

       - 推荐"拷源码集成"而非 Gradle 依赖,避免旧库在新环境下的兼容问题

       - 图标用 VectorDrawable(SVG 矢量),避免分辨率适配问题

       - 菜单项别超过 5 个:太多会超出屏幕、动画变慢、用户选择困难

       - Compose 时代:如果项目已全面 Compose,考虑用 DropdownMenu + 自定义动画替代,Context-Menu.Android 本身不兼容 Compose

       - 替代库:FloatingActionMenu、BoomMenu、CircularMenu 等,各有风格,按设计稿选

9、总结

Context-Menu.Android 是 Yalantis 出品的 Android 上下文菜单库,核心价值是把"长按弹出菜单"从朴素的白底列表,升级为带图标、带描述、带动画、可定制背景的炫酷浮层。API 简洁(MenuObject + ContextMenuDialogFragment),集成快,设计感拉满——尤其适合"图片/社交/文件管理"类 App 的长按操作场景。

关键要点:

       - 定位:Yalantis 出品的自定义上下文菜单库,长按弹出带图标动画的浮层菜单

       - 核心 API:MenuObject(定义菜单项)+ ContextMenuDialogFragment(承载与弹出)

       - 可定制:图标、描述、背景色/Drawable、弹出方向、背景模糊、动画

       - 注意:库较久未更新(2018),建议拷源码集成而非 Gradle 依赖

       - Compose 项目需另寻方案(此库不兼容 Compose)

对于需要"长按弹出带图标动画菜单"的 Android 开发者而言,Context-Menu.Android 是一个"拿来即用 + 可学可改"的优秀选择。即使因为它的年龄而最终选择自己写,Yalantis 这套代码也是"如何实现自定义浮层菜单"的教科书级参考——动画怎么编排、坐标怎么对齐、点击怎么分发,读一遍就懂。好库的价值不只在于"省时间",还在于"教你思路"。

参考资料:

        Yalantis/Context-Menu.Android(GitHub 官方仓库)

        Yalantis/Side-Menu.Android(姐妹库:侧滑菜单)

相关推荐

精选
Airbnb开源项目
开源

Airbnb开源项目

Airbnb Engineering & Data ScienceAirflow Use Apache Airflow (incubating) to author workflows as directed acyclic graphs (DAGs) of tasks12,263Airpal Web UI for PrestoDB2,502Aerosolve A machine learning

1.8k
OkHttp线程池和连接池
开源

OkHttp线程池和连接池

OkHttp线程池和连接池了解了OkHttp的网络请求流程以及拦截器实现原理,再关注OkHttp中两个重要的:OkHttp的线程池和连接池。1、OkHttp线程池在OkHttp网络请求流程一文中,我们分析了OkHttp异步和同步请求流程。请求最后都在Dispatcher中分发调度处理,最后被ExecutorService执行。1.1、DispatcherDispatcher中执行任务的执行器是ex

5.2k
优美的开源动效库:Lottie
开源

优美的开源动效库:Lottie

优美的开源动效库:Lottie1、强大的动效LottieLottie是一个适用于Android,iOS,Web和Windows的库,它可以使用Bodymovin解析以json格式导出的Adobe After Effects动画,并在移动设备和Web上原生渲染它们!GitHub:https://github.com/airbnb/lottie-androidLottie官网:http://airbn

4.3k