Giter Club home page Giter Club logo

petterpx / floatingx Goto Github PK

View Code? Open in Web Editor NEW
998.0 19.0 117.0 27.96 MB

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.

License: MIT License

Kotlin 97.84% Java 2.16%
floating floating-window kotlin-android android-lifecylce

floatingx's Introduction

FloatingX

image-20210810161316095

Codacy Badge Maven Central ktlint

FloatingX 一个灵活且强大的悬浮窗解决方案。

English Introduction

具体使用文档见这里

👏 特性

  • 支持 自定义隐藏显示动画;
  • 支持 多指触摸,精准决策触摸手势;
  • 支持 自定义是否保存历史位置及还原;
  • 支持 系统浮窗应用内浮窗局部浮窗
  • 支持 越界回弹边缘悬停边界设置;
  • 支持 以 layout, View 的方式设置浮窗内容;
  • 支持 自定义浮窗显示位置,支持辅助定位;
  • 支持 黑名单与白名单 功能,指定页面禁止显示浮窗等;
  • 支持 kotlin 构建扩展, 及对 Java 的友好兼容;
  • 支持显示位置[强行修复],应对特殊机型(需要单独开启)
  • 支持 局部浮窗,可在ViewGroup , Fragment , Activity 中进行显示;
  • 完善的日志系统,打开即可看到不同级别的Fx运行过程,更利于发现问题

👨‍💻‍ 依赖方式

Gradle

dependencies {
    implementation 'io.github.petterpx:floatingx:2.1.0'
}

🏄‍♀️ 效果图

全屏,activity,fragment,单view 小屏展示 非正常比例缩放屏幕
效果-展示1 演示-小屏 非正常比例缩放
屏幕旋转 功能演示
演示-旋转 演示-局部功能

完善的日志-查看器

开启日志查看器,将看到Fx整个运行轨迹,更便于发现问题以及追踪解决。同时支持自定义日志tag

App Activity ViewGroup
image-20210808123000851 image-20210808123414921 image-20210808123553402

👨‍🔧‍ 使用方式

全局悬浮窗管理

AndroidManifest (非必须)

// 如果不使用系统浮窗可以忽略此步骤(即FxScopeType.App时可跳过)
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />

kt

FloatingX.install {
	setContext(context)
        setLayout(R.layout.item_floating)
  	setScopeType(FxScopeType.SYSTEM_AUTO)
}.show()

Java

AppHelper helper = AppHelper.builder()
	.setContext(context)
        .setLayout(R.layout.item_floating)
  	.setScopeType(FxScopeType.SYSTEM_AUTO)
        .build();
FloatingX.install(helper).show();

局部悬浮窗管理

通用创建方式

kt

ScopeHelper.builder {
  setLayout(R.layout.item_floating)
}.toControl(activity)

kt && java

ScopeHelper.builder()
            .setLayout(R.layout.item_floating)
            .build()
            .toControl(activity)
            .toControl(fragment)
            .toControl(viewgroup)

对kt的扩展支持

activity创建悬浮窗
private val scopeFx by createFx {
    setLayout(R.layout.item_floating)
    build().toControl(this/Activity)
}
fragment创建悬浮窗
private val activityFx by createFx {
    setLayout(R.layout.item_floating)
    build().toControl(this/Fragment)
}
viewGroup创建悬浮窗
private val activityFx by createFx {
    setLayout(R.layout.item_floating)
    build().toControl(this/Viewgroup)
}

🤔 技术实现

System 级别悬浮窗 基于 WindowsManager 的实现方案,全局持有一个单独的悬浮窗 View ,通过 AppLifecycle 监听 Activity 生命周期,并在相应时机 插入到 WindowManager 上 ;

App 级别悬浮窗 基于 DecorView 的的实现方案,全局持有一个单独的悬浮窗 View ,通过 AppLifecycle 监听 Activity 生命周期,并在相应时机 插入到 DecorView 上 ;

View 级别悬浮窗,基于给定的 ViewGroup ;

Fragment 级别,基于其对应的 rootView ;

Acrtivity 级别,基于 DecorView 内部的 R.id.content ;

具体如下:

Activity-setContentView

具体见我的博客:源码分析 | Activity-setContentView

Ps: 为什么App级别悬浮窗 要插入到 DecorView ,而不是 R.id.content -> FrameLayout ?

插入到 DecorView 可以最大程度控制悬浮窗的自由度,即悬浮窗可以真正意义上[全屏]拖动。

插入到 content 中,其拖动范围其实为 应用视图范围 ,即摆放位置 受到 状态栏底部导航栏 以及 默认的 AppBar 影响, 比如当用户隐藏了状态栏或者导航栏,相对应的视图大小会发生改变,将影响悬浮窗的位置摆放。

👍 感谢

基础 悬浮窗View 的 初版实现** 源自 EnFloatingViewFloatingMagnetView 实现方式,并在其之上进行了彻底的重构与演变。

对于导航栏的测量部分代码来自,wenlu,并在其之上增加了更多适配,已覆盖市场95%机型,可以说是目前能搜到的唯一可以准确测量的工具。

关于我

欢迎关注我的公众号,期待一同进步,如果有使用上的问题,也可以加我微信。

微信Petterpx

Petterp-wechat

floatingx's People

Contributors

codacy-badger avatar goooler avatar greyfreedom avatar petterpx avatar y4n9b0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

floatingx's Issues

添加自定义View,不能定义宽高的问题

com.petterp.floatingx.view.FxManagerView#inflateLayoutView

 val lp = layoutParams ?: LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )

这行的 layoutParams 是不是可以定义成 view.layoutParams

全局悬浮窗-show()优化

当前版本中,application级别浮窗,存在着两个显示方法,show()与show(Activity)

前者使用时利用了当前栈顶activity;
后者直接使用当前传递的activity。

但是前者的调用存在一定奇奇怪怪的问题,考虑到用户有多种可能性,有时用户不会主动在application里初始化时开启全局显示,但后续第一次使用时却直接使用了show(),那么此时就存在没法获取到栈顶activity的问题。

之所以没有默认全局监听,主要是考虑到性能,但是如果使用时很麻烦,那么此时的这一点性能就没有必要照顾了。考虑了诸多方式,最终在性能与使用简易方面必须做一个抉择,思路如下:

在ContentProvider里新启一个 ApplicationLifecycle 监听,此监听的目的是为了保留一个全局Activity,此监听不会cancel关闭,默认处于打开状态,并且向外主动暴露当前栈顶activity。

如果大家有其他解法,也欢迎下面回复。

在onresume 里面发生异常 java.lang.IllegalArgumentException

android.view.WindowManagerGlobal.findViewLocked (WindowManagerGlobal.java:543)
android.view.WindowManagerGlobal.updateViewLayout (WindowManagerGlobal.java:437)
android.view.WindowManagerImpl.updateViewLayout (WindowManagerImpl.java:101)
android.widget.PopupWindow.update (PopupWindow.java:2221)
android.widget.PopupWindow.update (PopupWindow.java:2342)
android.widget.PopupWindow.alignToAnchor (PopupWindow.java:2512)
android.widget.PopupWindow.access$000 (PopupWindow.java:113)
android.widget.PopupWindow$1.onViewAttachedToWindow (PopupWindow.java:247)
android.view.View.dispatchAttachedToWindow (View.java:19876)
android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3508)
android.view.ViewGroup.addViewInner (ViewGroup.java:5317)
android.view.ViewGroup.addView (ViewGroup.java:5089)
android.view.ViewGroup.addView (ViewGroup.java:5029)
android.view.ViewGroup.addView (ViewGroup.java:5002)

com.petterp.floatingx.impl.control.FxAppControlImpl.attach$lib_floatingx_debug (FxAppControlImpl.kt:103)
com.petterp.floatingx.impl.lifecycle.FxLifecycleCallbackImpl.onActivityResumed (FxLifecycleCallbackImpl.kt:92)

android.app.Application.dispatchActivityResumed (Application.java:453)
android.app.Activity.dispatchActivityResumed (Activity.java:1317)
android.app.Activity.onResume (Activity.java:1856)
androidx.fragment.app.FragmentActivity.onResume (FragmentActivity.java:434)
base.sys.activity.BaseActivity.onResume (BaseActivity.java:196)
com.voiceroom.ui.VoiceRoomActivity.onResume (VoiceRoomActivity.kt:152)

如何全局使用?

我把以下代码添加了,AndroidManifest.xml也设置了Application,但是啥也没发生,也没有日志。

open class App: Application() {
    override fun onCreate() {
        super.onCreate()
        Log.d("AAA", "onCreate: onCreate: ")
        FloatingX.init {
            // 设置context
            setContext(this@App)
            // 设置悬浮窗layout
            setLayout(R.layout.layout_floating)
            // 设置悬浮窗默认方向
            setGravity(Direction.RIGHT_OR_BOTTOM)
            // 设置是否启用日志
            setEnableLog(true)

            // 启用辅助方向
            setEnableAssistDirection(0f, 0f, 0f, 100f)
            // 设置x轴默认坐标
//            setX()
            // 设置y轴默认坐标
//            setY()

            // 设置启用边缘吸附
            setEnableEdgeAdsorption(true)
            // 设置边缘偏移量
            setEdgeOffset(10f)
            // 设置启用悬浮窗可屏幕外回弹
            setEnableScrollOutsideScreen(true)
            // 设置辅助方向辅助
            // 设置点击事件
//            setOnClickListener { }
            // 设置view-lifecycle监听
//            setViewLifecycle()

            // 设置启用悬浮窗位置修复
            setEnableAbsoluteFix(true)
            // 设置启用动画
            setEnableAnimation(true)
            // 设置启用动画实现

            // 设置底部偏移量
            setBottomBorderMargin(100f)
            // 设置顶部偏移量
//            setTopBorderMargin(100f)
            // 设置左侧偏移量
            setLeftBorderMargin(100f)
            // 设置右侧偏移量
            setRightBorderMargin(100f)

            // 设置允许触摸事件
            setEnableTouch(true)

            // 设置悬浮窗LayoutParams
//            setLayoutParams()
            // 设置要显示的activity
            addBlackClass(
                MainActivity::class.java,
            )
            // 设置允许全部activity显示悬浮窗,默认false
            setEnableAllBlackClass(true)

            // 设置tag-Activity生命周期回调时的触发
            setTagActivityLifecycle {
                onCreated { activity, bundle ->
                }
                onResumes { }
            }
            setEnableLog(true)
            // 只有调用了show,默认才会启用fx,否则fx不会自动插入activity
            show()
        }
    }
}

如何implementation

gradle配置如下:
repositories {
google()
mavenCentral()
}

然而执行结果是:
Failed to resolve: com.github.Petterpx:FloatingX:1.0-rc05

请问仓库地址是不是有变化?

动态设置文字

setLayout(R.layout.XX)
怎么给layout中的textView动态设置文字

频繁切换页面,引起黑屏崩溃

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/core/view/WindowInsetsCompat$Type;
        at com.petterp.floatingx.impl.control.FxAppControlImpl$windowsInsetsListener$2$1.onApplyWindowInsets(FxAppControlImpl.kt:25)
        at androidx.core.view.ViewCompat$1.onApplyWindowInsets(ViewCompat.java:2474)
        at android.view.View.dispatchApplyWindowInsets(View.java:11469)
        at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7406)
        at android.view.ViewGroup.newDispatchApplyWindowInsets(ViewGroup.java:7431)
        at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7413)
        at android.view.ViewRootImpl.dispatchApplyInsets(ViewRootImpl.java:2595)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2999)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2252)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8791)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1140)
        at android.view.Choreographer.doCallbacks(Choreographer.java:962)
        at android.view.Choreographer.doFrame(Choreographer.java:887)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1125)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:257)
        at android.app.ActivityThread.main(ActivityThread.java:8259)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1006)

hide方法无效!

调用hide方法隐藏悬浮窗, 点击跳转到新的activity又显示出来了。请问怎么回事? 这个hide方法的有效期或者生命周期是怎么样的?

设置右上角 怎么不起作用

private val fragmentFx by createFx {
        setLayout(R.layout.....)
        .setGravity(FxGravity.RIGHT_OR_TOP)
            .build().toControl(this@HomeFragment)
    }
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_careModel"
    android:layout_width="40dp"
    android:layout_height="wrap_content"
    android:alpha="0.8"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingTop="10dp"
    android:paddingBottom="10dp">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/icon_cardmodel_heart" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text=""
        android:gravity="center"
        android:textColor="@color/white"
        android:textSize="16sp"
        />

</LinearLayout>

这样写 还是在左上角·

方案缺陷

不知道作者有没有考虑过如何解决:切换 Activity 时悬浮控件短暂消失重绘问题

AndroidStudio4.1.3 编译问题

大佬好,请问我用了AndroidStudio4.1.3开启最新的专案..会出这错误 请问能如何处理呢?谢谢
image
另外我按了 Use JDK from project structure 后,会跳出这错误
This version of the Android Support plugin for IntelliJ IDEA (or Android Studio) cannot open this project, please retry with version 2020.3.1 or newer.
再拜托您帮忙小弟解答下,谢谢

增加不想显示的界面

现在是支持所有显示的 和 固定想要显示的 可否增加一个 不想显示某几个页面的api

无法依赖

AS版本:Android Studio Chipmunk
gradle版本:7.2.1
kotlin版本:1.6.21
是否AndroidX:是
FloatingX版本:1.0

问题:无论是否开启代理,依赖库下载过程未出错,但代码里找不到也无法使用 FloatingX

使用过程中bugly上报视图空指针异常。

08-24 17:48:28.381 7140 7140 E AndroidRuntime: java.lang.NullPointerException: null cannot be cast to non-null type android.view.ViewGroup

16008-24 17:48:28.381 7140 7140 E AndroidRuntime: at java.util.Objects.requireNonNull(Objects.java:245)
16108-24 17:48:28.381 7140 7140 E AndroidRuntime: at com.petterp.floatingx.view.FxMagnetView.v(SourceFile:1)
16208-24 17:48:28.381 7140 7140 E AndroidRuntime: at com.petterp.floatingx.view.FxMagnetView.s(SourceFile:1)
16308-24 17:48:28.381 7140 7140 E AndroidRuntime: at com.petterp.floatingx.view.FxMagnetView.b(Unknown Source:0)
16408-24 17:48:28.381 7140 7140 E AndroidRuntime: at com.petterp.floatingx.view.b.run(Unknown Source:4)
16508-24 17:48:28.381 7140 7140 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938)
16608-24 17:48:28.381 7140 7140 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
16708-24 17:48:28.381 7140 7140 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:233)
16808-24 17:48:28.381 7140 7140 E AndroidRuntime: at android.os.Looper.loop(Looper.java:344)
16908-24 17:48:28.381 7140 7140 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:8204)
17008-24 17:48:28.381 7140 7140 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
17108-24 17:48:28.381 7140 7140 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:589)
17208-24 17:48:28.381 7140 7140 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1071)

provider 冲突问题

建议改成 android:authorities="${applicationId}.impl.lifecycle.fxlifecycleprovider"
不然整个手机就只能装一个应用了

发现一个bug

view的浮窗设置点击事件后一点击Fragment其他的点击事件会失效

在安卓11,机型redmi k2o pro上没有任何效果

参考主页以下方式创建悬浮窗,在安卓11上没有任何效果,机型 redmi k2o pro ,辛苦支持

AppHelper helper = AppHelper.builder()
.setLayout(R.layout.item_floating)
.setLayoutView(view)
.enableFx()
.build();
FloatingX.init(helper);

多次显示隐藏会bug

Process: com.jz.jxz, PID: 31958
    java.lang.IllegalStateException: initFxView -> Error,check your layoutId or layoutView.
        at com.petterp.floatingx.view.FxManagerView.initView(FxManagerView.kt:63)
        at com.petterp.floatingx.view.FxManagerView.init(FxManagerView.kt:57)
        at com.petterp.floatingx.impl.control.FxBasisControlImpl.initManager(FxBasisControlImpl.kt:210)
        at com.petterp.floatingx.impl.control.FxBasisControlImpl.initManagerView(FxBasisControlImpl.kt:206)
        at com.petterp.floatingx.impl.control.FxScopeControl.show(FxScopeControl.kt:22)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.