{"id":26022181,"url":"https://github.com/Petterpx/FloatingX","last_synced_at":"2025-03-06T09:54:44.085Z","repository":{"id":37430188,"uuid":"372486273","full_name":"Petterpx/FloatingX","owner":"Petterpx","description":"Android上强大的悬浮窗组件，支持 系统浮窗(需要权限)、应用内浮窗(无权限)、局部悬浮(View)，支持边缘吸附、回弹、自定义动画、位置保存、窗口化及分屏后位置修复等。Android without permission suspension window(App), support global(View), local suspension, support edge adsorption, rebound, custom animation, position saving, windowing and split-screen position repair.","archived":false,"fork":false,"pushed_at":"2025-02-10T16:34:20.000Z","size":28803,"stargazers_count":1243,"open_issues_count":5,"forks_count":143,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-02-10T17:35:43.713Z","etag":null,"topics":["android-lifecylce","floating","floating-window","kotlin-android"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Petterpx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-31T11:41:53.000Z","updated_at":"2025-02-10T16:34:03.000Z","dependencies_parsed_at":"2024-04-09T07:33:40.242Z","dependency_job_id":"dd50828a-5a3d-4a45-94c2-0eeeeb98c111","html_url":"https://github.com/Petterpx/FloatingX","commit_stats":null,"previous_names":[],"tags_count":80,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Petterpx%2FFloatingX","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Petterpx%2FFloatingX/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Petterpx%2FFloatingX/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Petterpx%2FFloatingX/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Petterpx","download_url":"https://codeload.github.com/Petterpx/FloatingX/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242187653,"owners_count":20086217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android-lifecylce","floating","floating-window","kotlin-android"],"created_at":"2025-03-06T09:54:36.387Z","updated_at":"2025-03-06T09:54:44.062Z","avatar_url":"https://github.com/Petterpx.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# FloatingX\n\n\n\n![image-20210810161316095](https://tva1.sinaimg.cn/large/008i3skNly1gtbrg85hlhj61040k80ui02.jpg)\n\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a9edd107b5444b7ca31738f5a96b3cb9)](https://app.codacy.com/gh/Petterpx/FloatingX?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=Petterpx/FloatingX\u0026utm_campaign=Badge_Grade_Settings)\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.petterpx/floatingx)](https://search.maven.org/search?q=g:io.github.petterpx%20AND%20a:floatingx)\n[![ktlint](https://img.shields.io/badge/code%20style-%E2%9D%A4-FF4081.svg)](https://ktlint.github.io/) \n\n**FloatingX** 一个灵活且强大的悬浮窗解决方案。\n\n[English Introduction](https://github.com/Petterpx/FloatingX/blob/main/README_EN.md)\n\n[具体使用文档见这里](https://cskf7l0wab.feishu.cn/wiki/wikcnLLBCe3fIDUTAzrEg754tzc)\n\n## 👏 特性 \n\n- 支持 **JetPack Compose**\n- 支持 **浮窗半隐藏模式**\n- 支持 **自定义隐藏显示动画**;\n- 支持 **多指触摸**，精准决策触摸手势;\n- 支持 自定义是否保存历史位置及还原;\n- 支持 **系统浮窗**、**应用内浮窗**、**局部浮窗**；\n- 支持 **越界回弹**，**边缘悬停**，**边界设置**;\n- 支持 以 **layout**, **View**  的方式设置浮窗内容；\n- 支持 自定义浮窗显示位置，**支持辅助定位**;\n- 支持 **黑名单与白名单** 功能，指定页面禁止显示浮窗等;\n- 支持 `kotlin` 构建扩展, 及对 `Java` 的友好兼容;\n- 支持显示位置[强行修复],应对特殊机型(需要单独开启)\n- 支持 **局部浮窗**，可在`ViewGroup` , `Fragment` , `Activity` 中进行显示；\n- 完善的日志系统，打开即可看到不同级别的Fx运行过程,更利于发现问题\n\n## 👨‍💻‍ 依赖方式\n\n### Gradle\n\n```groovy\ndependencies {\n    implementation 'io.github.petterpx:floatingx:2.3.4'\n  \n    // system浮窗\u0026\u0026compose时需要导入\n    // 记得AppHelper里调用 enableComposeSupport()\n    implementation 'io.github.petterpx:floatingx-compose:2.3.4'\n}\n```\n\n\n## 🏄‍♀️ 效果图\n\n| 全屏,activity,fragment,单view                                | 小屏展示                                                     | 非正常比例缩放屏幕                                           |\n| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |\n| ![效果-展示1](https://github.com/Petterpx/FloatingX/blob/main/image/fx-api-simple.gif?raw=true) | ![演示-小屏](https://github.com/Petterpx/FloatingX/blob/main/image/fx-small-gif.gif?raw=true) | ![非正常比例缩放](https://github.com/Petterpx/FloatingX/blob/main/image/fx-view-deformed-simple.gif?raw=true) |\n\n| 屏幕旋转                                                     | 功能演示                                                     |      |\n| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- |\n| ![演示-旋转](https://github.com/Petterpx/FloatingX/blob/main/image/fx-rotate-simple.gif?raw=true) | ![演示-局部功能](https://github.com/Petterpx/FloatingX/blob/main/image/fx-api-simple.gif?raw=true) |      |\n\n### 完善的日志-查看器\n\n开启日志查看器，将看到Fx整个运行轨迹，更便于发现问题以及追踪解决。同时支持自定义日志tag\n\n| App                                                          | Activity                                                     | ViewGroup                                                    |\n| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |\n| ![image-20210808123000851](https://tva1.sinaimg.cn/large/008i3skNly1gtbk1ujkqfj31160s8444.jpg) | ![image-20210808123414921](https://tva1.sinaimg.cn/large/008i3skNly1gt99vralyqj313o0r4jwk.jpg) | ![image-20210808123553402](https://tva1.sinaimg.cn/large/008i3skNly1gt99xfpfwgj311y0jctc8.jpg) |\n\n\n\n## 👨‍🔧‍ 使用方式\n\n### 全局悬浮窗管理\n\n**AndroidManifest (非必须)**\n\n```xml\n// 如果不使用系统浮窗可以忽略此步骤(即FxScopeType.App时可跳过)\n\u003cuses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\" /\u003e\n\u003cuses-permission android:name=\"android.permission.SYSTEM_OVERLAY_WINDOW\" /\u003e\n```\n\n**kt**\n\n```kotlin\nFloatingX.install {\n\tsetContext(context)\n        setLayout(R.layout.item_floating)\n  \tsetScopeType(FxScopeType.SYSTEM_AUTO)\n}.show()\n```\n\n**Java**\n\n```java\nAppHelper helper = AppHelper.builder()\n\t.setContext(context)\n        .setLayout(R.layout.item_floating)\n  \t.setScopeType(FxScopeType.SYSTEM_AUTO)\n        .build();\nFloatingX.install(helper).show();\n```\n\n\n\n### 局部悬浮窗管理\n\n#### 通用创建方式\n\n**kt**\n\n```kotlin\nScopeHelper.builder {\n  setLayout(R.layout.item_floating)\n}.toControl(activity)\n```\n\n**kt \u0026\u0026 java**\n\n```kotlin\nScopeHelper.builder()\n            .setLayout(R.layout.item_floating)\n            .build()\n            .toControl(activity)\n            .toControl(fragment)\n            .toControl(viewgroup)\n```\n\n#### 对kt的扩展支持\n\n##### activity创建悬浮窗\n\n```kotlin\nprivate val scopeFx by createFx {\n    setLayout(R.layout.item_floating)\n    build().toControl(this/Activity)\n}\n\n```\n\n##### fragment创建悬浮窗\n\n```kotlin\nprivate val activityFx by createFx {\n    setLayout(R.layout.item_floating)\n    build().toControl(this/Fragment)\n}\n```\n\n##### viewGroup创建悬浮窗\n\n```kotlin\nprivate val activityFx by createFx {\n    setLayout(R.layout.item_floating)\n    build().toControl(this/Viewgroup)\n}\n```\n\n## 🤔 技术实现\n\u003e **System** 级别悬浮窗 基于 `WindowsManager` 的实现方案，全局持有一个单独的悬浮窗 `View` ,通过 `AppLifecycle` 监听 `Activity` 生命周期，并在相应时机 插入到 `WindowManager` 上 ;\n\n\u003e **App** 级别悬浮窗 基于 `DecorView` 的的实现方案，全局持有一个单独的悬浮窗 `View` ,通过 `AppLifecycle` 监听 `Activity` 生命周期，并在相应时机 插入到 `DecorView` 上 ;\n\u003e\n\u003e **View** 级别悬浮窗，基于给定的 `ViewGroup` ;\n\u003e\n\u003e **Fragment** 级别，基于其对应的 `rootView` ;\n\u003e\n\u003e **Acrtivity** 级别,基于 `DecorView` 内部的 `R.id.content` ;\n\n具体如下：\n\n\u003cimg src=\"https://tva1.sinaimg.cn/large/008i3skNly1gr20ks7780j30rc0i5dim.jpg\" alt=\"Activity-setContentView\"  /\u003e\n\n具体见我的博客：[源码分析 | Activity-setContentView](https://juejin.cn/post/6897453195342610445) \n\nPs: 为什么App级别悬浮窗 要插入到 `DecorView` ,而不是 **R.id.content** -\u003e `FrameLayout` ?\n\n\u003e 插入到 `DecorView` 可以最大程度控制悬浮窗的自由度，即悬浮窗可以真正意义上[`全屏`]拖动。\n\u003e\n\u003e 插入到 `content` 中,其拖动范围其实为 **应用视图范围** ,即摆放位置 受到 **状态栏** 和 **底部导航栏** 以及 默认的 `AppBar` 影响, 比如当用户隐藏了状态栏或者导航栏，相对应的视图大小会发生改变，将影响悬浮窗的位置摆放。\n\n\n\n## 👍 感谢\n\n基础 **悬浮窗View** 的 初版实现思想 源自 [EnFloatingView](https://github.com/leotyndale/EnFloatingView) 的 [FloatingMagnetView](https://github.com/leotyndale/EnFloatingView/blob/master/floatingview/src/main/java/com/imuxuan/floatingview/FloatingMagnetView.java) 实现方式，并在其之上进行了彻底的重构与演变。\n\n对于导航栏的测量部分代码来自，wenlu,并在其之上增加了更多适配，已覆盖市场95%机型，可以说是目前能搜到的唯一可以准确测量的工具。\n\n## 关于我\n\n欢迎关注我的公众号，期待一同进步，如果有使用上的问题，也可以加我微信。\n\n**微信**：**Petterpx**\n\n![Petterp-wechat](https://user-images.githubusercontent.com/41142188/226162520-93796619-81ca-4e61-bfff-4a5b95e4fa0b.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPetterpx%2FFloatingX","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPetterpx%2FFloatingX","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPetterpx%2FFloatingX/lists"}