Skip to content

Repository files navigation

FloatMenu

🎯 一个轻量级、易用的 Android 悬浮菜单库

APILicenseRelease

FloatMenu Demo


✨ 特性

特性描述
轻量级无第三方依赖,体积小巧
🎨 高度可定制支持自定义背景、图标、菜单项、颜色等
📍 灵活定位支持停靠在屏幕左侧或右侧
🔔 红点提醒支持红点数字提醒功能
🎯 Unity 支持兼容 Unity3D 游戏引擎
📱 Android 11+支持最新 Android 版本
🔄 AndroidX完全兼容 AndroidX
无障碍完整的无障碍功能支持

📦 依赖

方式一:GitHub Packages(推荐)

在项目的 settings.gradle 中添加仓库:

dependencyResolutionManagement {
repositories {
maven {
url ="https://maven.pkg.github.com/ColdBrando/FloatMenuSample"
credentials {
username ="你的GitHub用户名"
password ="你的GitHub Token"// 或使用 GITHUB_TOKEN 环境变量
}
}
}
}

build.gradle 中添加依赖:

dependencies {
implementation 'com.github.fanofdemo:FloatMenu:2.4.3'
}

注意: GitHub Token 需要有 read:packages 权限。


方式二:JitPack(最简单)

无需配置仓库,直接添加依赖:

dependencies {
implementation 'com.github.ColdBrando:FloatMenuSample:v2.4.0'
}

settings.gradle 中添加:

repositories {
maven { url 'https://jitpack.io' }
}

方式三:直接集成模块

FloatMenu 模块复制到你的项目:

# 克隆项目
git clone https://github.com/ColdBrando/FloatMenuSample.git
# 复制 FloatMenu 模块到你的项目
cp -r FloatMenuSample/FloatMenu your-project/

settings.gradle 中添加:

include ':FloatMenu'

build.gradle 中添加:

dependencies {
implementation project(':FloatMenu')
}

🚀 快速开始

极简用法(3行代码)

// 1. 创建菜单项List<FloatItem> items = newArrayList<>();
items.add(newFloatItem("首页", R.drawable.icon_home));
items.add(newFloatItem("客服", R.drawable.icon_service));
items.add(newFloatItem("消息", R.drawable.icon_msg));
// 2. 创建并显示悬浮菜单FloatMenu.create(this)
.logo(R.drawable.logo)
.items(items)
.show();

标准用法(带监听)

FloatMenu.create(this)
.logo(R.drawable.logo)
.items(items)
.listener(newFloatMenuView.OnMenuClickListener() {
@OverridepublicvoidonItemClick(intposition, Stringtitle) {
Toast.makeText(this, "点击了: " + title, Toast.LENGTH_SHORT).show();
}
@Overridepublicvoiddismiss() {
// 菜单关闭回调
}
})
.show();

高级配置

FloatMenu.create(context)
.logo(R.drawable.logo)
.items(items)
.location(FloatMenu.LEFT) // 停靠在左侧
.autoShrink(5000) // 5秒后自动贴边
.showRedDot(true) // 显示红点数字
.backgroundColor(0xFF4CAF50) // 自定义背景颜色
.drawCircleBg(true) // 绘制圆形背景
.listener(listener)
.show();

📖 详细文档


🎯 核心功能详解

交互逻辑

┌─────────────┐
│ 贴边状态 │ ──点击──> ┌─────────────┐
│ (50%隐藏) │ │ 正常状态 │
└─────────────┘ └─────────────┘
│
点击
↓
┌─────────────┐
│ 展开状态 │
└─────────────┘

功能说明

1. 拖动限制

悬浮球在拖动时始终保持在屏幕边界内:

  • X轴范围:[0, 屏幕宽度 - logo宽度]
  • Y轴范围:[状态栏高度, 屏幕高度 - logo高度]
  • 手指中心与logo圆心保持一致

2. 自动贴边

可配置延时后自动贴边至屏幕边缘:

  • 默认 3 秒后自动贴边
  • 贴边后 logo 的 50% 在屏幕内,50% 超出边界
  • 使用平滑动画过渡(300ms 贴边,200ms 恢复)

3. 状态管理

状态描述
正常状态logo 完全可见,可点击展开菜单
贴边状态logo 的 50% 超出屏幕,点击先恢复
展开状态菜单已展开,点击 logo 关闭菜单
拖动状态正在拖动中,暂停贴边计时

🔧 在 Service 中使用

在 Service 中使用悬浮菜单可以让菜单在应用外持续显示。

步骤一:添加权限

<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW" />

步骤二:创建 Service

publicclassFloatMenuServiceextendsService {
privateFloatLogoMenumFloatMenu;
@OverridepublicvoidonCreate() {
super.onCreate();
initFloatMenu();
}
@OverridepublicintonStartCommand(Intentintent, intflags, intstartId) {
if (mFloatMenu != null) {
mFloatMenu.show();
}
returnSTART_STICKY;
}
@OverridepublicvoidonDestroy() {
super.onDestroy();
if (mFloatMenu != null) {
mFloatMenu.destroyFloat();
}
}
privatevoidinitFloatMenu() {
List<FloatItem> items = newArrayList<>();
items.add(newFloatItem("首页", R.drawable.icon_home));
mFloatMenu = FloatMenu.create(getApplicationContext())
.logo(R.drawable.logo)
.items(items)
.location(FloatMenu.LEFT)
.show();
}
}

步骤三:注册 Service

<serviceandroid:name=".FloatMenuService"android:enabled="true"android:exported="false" />

步骤四:启动 Service

// 启动服务Intentintent = newIntent(this, FloatMenuService.class);
startService(intent);
// 停止服务Intentintent = newIntent(this, FloatMenuService.class);
stopService(intent);

📊 API 文档

FloatMenu.Builder

方法必须默认值说明
logo(int resId)-设置 logo 图标(资源 ID)
logo(Bitmap bitmap)-设置 logo 图标(Bitmap)
items(List<FloatItem>)-设置菜单项列表
listener(OnMenuClickListener)null设置点击监听器
location(int)RIGHT停靠位置(LEFT/RIGHT)
autoShrink(int)3000自动贴边延时(0=不贴边)
showRedDot(boolean)false是否显示红点数字
drawCircleBg(boolean)true是否绘制圆形背景
backgroundColor(int)系统默认背景颜色
backgroundDrawable(Drawable)系统默认背景 Drawable
show()-显示悬浮菜单

FloatItem 构造方法

// 方法1:只有标题FloatItem(Stringtitle)
// 方法2:标题 + 图标资源IDFloatItem(Stringtitle, intdrawableId)
// 方法3:标题 + 图标BitmapFloatItem(Stringtitle, Bitmapbitmap)
// 方法4:完整参数FloatItem(Stringtitle, intpressColor, intnormalColor, Bitmapicon, StringdotNum)

🎨 自定义悬浮窗

方法一:继承 BaseFloatDialog

publicclassMyFloatDialogextendsBaseFloatDialog {
@OverridepublicViewonCreateView(LayoutInflaterinflater) {
Viewview = inflater.inflate(R.layout.my_float_dialog, null);
returnview;
}
}
// 使用MyFloatDialogdialog = newMyFloatDialog();
dialog.show(this);

方法二:实现 GetViewCallback

BaseFloatDialogdialog = newBaseFloatDialog(this, newBaseFloatDialog.GetViewCallback() {
@OverridepublicViewonCreateView(LayoutInflaterinflater) {
Viewview = inflater.inflate(R.layout.my_float_dialog, null);
// 初始化视图returnview;
}
});
dialog.show();

🔐 权限说明

使用场景权限要求
应用内悬浮无需权限
桌面悬浮SYSTEM_ALERT_WINDOW

添加悬浮窗权限:

<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW" />

📱 系统要求

项目要求
最低 SDKAPI 11 (Android 3.0)
编译 SDKAPI 36
Java 版本Java 17
Gradle 版本8.5+

📸 示例应用

查看 FloatMenuDemo 模块了解完整用法。

Demo 应用展示了:

  • ✅ Activity 中使用悬浮菜单
  • ✅ Service 中使用悬浮菜单
  • ✅ 自定义配置
  • ✅ 生命周期管理

📝 更新日志

v2.4.0 (2024-01-30)

新增功能

  • 简化的 FloatMenu API,提供链式调用
  • 新增 FloatMenuService 支持 Service 中使用悬浮菜单
  • 新增动态配置方法 setLogoDrawNum()setLogoDrawBg()

Bug 修复

  • 修复右侧菜单展开时跳到左侧的问题
  • 修复菜单展开后 logo 背景消失的问题
  • 修复 lint 警告和无障碍支持

优化

  • 移除 logo 拖动时的旋转动画
  • 统一背景颜色
  • 代码重构,简化定位逻辑

查看 完整更新日志


🤝 贡献

欢迎提交 Issue 和 Pull Request!

详情请参阅 贡献指南


📄 许可证

BSD 3-Clause License
Copyright (c) 2016, Shanghai YUEWEN Information Technology Co., Ltd.
All rights reserved.

详细内容见项目根目录的 LICENSE 文件。


📞 联系方式


如果这个项目对你有帮助,请给个 ⭐️ Star 支持一下!

About

android 悬浮窗菜单,可在launcher或app中使用

Resources

Contributing

Stars

700 stars

Watchers

17 watching

Forks

Releases

Packages

Contributors

Languages