Skip to content

🔥 EasyFloat:浮窗从未如此简单

Notifications You must be signed in to change notification settings

bbbBBBSG/EasyFloat

Repository files navigation

EasyFloat:Android浮窗框架

EasyFloat:浮窗从未如此简单

特点功能:

  • 支持单页面浮窗,无需权限申请
  • 支持全局浮窗、应用前台浮窗,需要授权悬浮窗权限
  • 自动权限检测、自动跳转浮窗权限管理页、自动处理授权结果
  • 支持系统浮窗的页面过滤
  • 支持拖拽,支持各种状态的回调
  • 支持默认位置的设定,支持对齐方式和偏移量的设定
  • 支持创建多个单页面浮窗、多个系统浮窗,Tag进行区分
  • 支持出入动画的设定,有默认动画,可自行替换(策略模式)
  • 根据浮窗复杂度、重要性,可自主选择前后台Service
  • 使用简单、链式调用,Kotlin DSL按需回调状态
  • 支持xml直接使用,满足拖拽控件的需求
  • 支持解锁更多姿势,如:拖拽缩放、通知弹窗...
权限申请 系统浮窗
前台和过滤 状态回调 拓展使用

关于集成:

  • 在项目的根目录的build.gradle添加:
allprojects {
    repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}
  • 在应用模块的build.gradle添加:
dependencies {
    implementation 'com.github.princekin-f:EasyFloat:1.0.5'
}

一行代码搞定Android浮窗,浮窗从未如此简单:

EasyFloat.with(this).setLayout(R.layout.float_test).show()

关于初始化:

  • 全局初始化为非必须;
  • 当浮窗为仅前台显示,或者设置了浮窗过滤页面;
  • 需要在项目的Application中进行全局初始化,进行页面生命周期检测。
EasyFloat.init(this, isDebug)

关于权限声明:

  • 权限声明为非必须;
  • 如果使用到系统浮窗(ShowPattern.ALL_TIMEShowPattern.FOREGROUND);
  • 需要在AndroidManifest.xml进行权限声明。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  • 在使用到系统浮窗的情况下,不仅要声明浮窗权限,还要声明启动系统浮窗的服务;
  • 该服务和上述系统浮窗权限,成对出现。
<service android:name="com.lzf.easyfloat.service.FloatService" />

关于前台Service:

  • 可根据系统浮窗的重要性和复杂度,选择是否开启前台Service(默认后台Service);
  • Android 9.0开始,前台Service需要在AndroidManifest.xml进行权限声明。
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

PS:前台Service会在通知栏创建一条消息,有默认实现,也可进行消息自定义。

完整使用示例:

EasyFloat.with(this)
    // 设置浮窗xml布局文件,并可设置详细信息
    .setLayout(R.layout.float_app, OnInvokeView {  })
    // 设置浮窗显示类型,默认只在当前Activity显示,可选一直显示、仅前台显示
    .setShowPattern(ShowPattern.ALL_TIME)
    // 设置吸附方式,共15种模式,详情参考SidePattern
    .setSidePattern(SidePattern.RESULT_HORIZONTAL)
    // 设置浮窗的标签,用于区分多个浮窗
    .setTag("testFloat")
    // 设置浮窗是否可拖拽
    .setDragEnable(true)
    // 设置浮窗固定坐标,ps:设置固定坐标,Gravity属性和offset属性将无效
    .setLocation(100, 200)
    // 设置浮窗的对齐方式和坐标偏移量
    .setGravity(Gravity.END or Gravity.CENTER_VERTICAL, 0, 200)
    // 设置宽高是否充满父布局,直接在xml设置match_parent属性无效
    .setMatchParent(widthMatch = false, heightMatch = false)
    // 设置Activity浮窗的出入动画,可自定义,实现相应接口即可(策略模式),无需动画直接设置为null
    .setAnimator(DefaultAnimator())
    // 设置系统浮窗的出入动画,使用同上
    .setAppFloatAnimator(AppFloatDefaultAnimator())
    // 设置系统浮窗的不需要显示的页面
    .setFilter(MainActivity::class.java, SecondActivity::class.java)
    // 是否启动前台Service,仅针对系统浮窗;有默认的Notification,可不传
    .startForeground(true, floatNotification(this))
    // 浮窗的一些状态回调,如:创建结果、显示、隐藏、销毁、touchEvent、拖拽过程、拖拽结束。
    // ps:通过Kotlin DSL实现的回调,可以按需复写方法,用到哪个写哪个
    .registerCallbacks {
        createResult { isCreated, msg, view ->  }
        show {  }
        hide {  }
        dismiss {  }
        touchEvent { view, motionEvent ->  }
        drag { view, motionEvent ->  }
        dragEnd {  }
    }
    // 创建浮窗(这是关键哦😂)
    .show()

在Java中使用Kotlin DSL不是很方便,状态回调还有一种常规的接口方式:

.registerCallbacks(new OnFloatCallbacks() {
        @Override
        public void createdResult(boolean isCreated, @Nullable String msg, @Nullable View view) { }

        @Override
        public void show(@NotNull View view) { }

        @Override
        public void hide(@NotNull View view) { }

        @Override
        public void dismiss() { }

        @Override
        public void touchEvent(@NotNull View view, @NotNull MotionEvent event) { }

        @Override
        public void drag(@NotNull View view, @NotNull MotionEvent event) { }

        @Override
        public void dragEnd(@NotNull View view) { }
})

如果想要在Java是使用Kotlin DSL,可以参考Demo。

悬浮窗权限检测,可用于设置引导页面:

  • 无需主动进行权限申请,创建结果、申请结果可在OnFloatCallbackscreatedResult获取。
PermissionUtils.checkPermission(this)

Activity浮窗的相关API:

// 关闭浮窗
dismiss(activity: Activity? = null, floatTag: String? = null)

// 隐藏浮窗
hide(activity: Activity? = null, floatTag: String? = null)

// 显示浮窗
show(activity: Activity? = null, floatTag: String? = null)

// 设置是否可拖拽
setDragEnable(activity: Activity? = null, dragEnable: Boolean, floatTag: String? = null )

// 浮窗是否显示
isShow(activity: Activity? = null, floatTag: String? = null)

PS:? = null 代表可选参数,不填也行,默认值为null。下同。

系统浮窗的相关API:

// 关闭浮窗
dismissAppFloat(context: Context, tag: String? = null)

// 隐藏浮窗
hideAppFloat(context: Context, tag: String? = null)

// 显示浮窗
showAppFloat(context: Context, tag: String? = null)

// 设置是否可拖拽
appFloatDragEnable(dragEnable: Boolean, tag: String? = null)

// 浮窗是否显示
appFloatIsShow(tag: String? = null)

// 添加单个浮窗过滤页面
filterActivity(activity: Activity, tag: String? = null)

// 添加多个浮窗过滤页面
filterActivities(tag: String? = null, vararg clazz: Class<*>)

// 移除单个浮窗过滤页面
removeFilter(activity: Activity, tag: String? = null)

// 移除多个浮窗过滤页面
removeFilters(tag: String? = null, vararg clazz: Class<*>)

// 清空过滤页面
clearFilters(tag: String? = null)

系统浮窗中使用EditText

1,为EditText设置点击事件,调用openInputMethod方法:

InputMethodUtils.openInputMethod(editText, tag)

2,软键盘关闭时,调用closedInputMethod方法:

InputMethodUtils.closedInputMethod(tag)

直接在xml布局使用拖拽控件:

<com.lzf.easyfloat.widget.activityfloat.FloatingView
    android:id="@+id/floatingView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">

    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@mipmap/ic_launcher_round" />

</com.lzf.easyfloat.widget.activityfloat.FloatingView>
  • 1.0.4及以下需要为FloatingView设置点击事件,不然无法拖拽:
floatingView.setOnClickListener {}

关于混淆:

-keep class com.lzf.easyfloat.** {*;}

关于感谢:


更新日志:

v 1.0.5:

  • 优化代码和功能,支持FloatCallbacks的按需调用(Kotlin DSL)。

v 1.0.4:

  • 可选择是否开启前台Service,可自定义通知栏消息。

v 1.0.3:

  • 修改魅族手机,权限申请回调异常的问题;
  • 为系统浮窗的EditText,提供了软键盘的打开、关闭后的焦点移除;
  • 但暂未提供软键盘的关闭监听方案,希望大家一起努力。

v 1.0.2:

  • 修改enum包名,解决Java特殊路径无法调用的问题;
  • 添加@JvmOverloads注解,支持对Java的方法重载。

About

🔥 EasyFloat:浮窗从未如此简单

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Kotlin 79.4%
  • Java 20.6%