Skip to content

Commit

Permalink
新增仅后台显示模式
Browse files Browse the repository at this point in the history
  • Loading branch information
princekin-f committed Jan 4, 2020
1 parent 3b101c0 commit d64c003
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 92 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ allprojects {
- **在应用模块的`build.gradle`添加:**
```
dependencies {
implementation 'com.github.princekin-f:EasyFloat:1.2.2'
implementation 'com.github.princekin-f:EasyFloat:1.2.3'
}
```

Expand All @@ -55,15 +55,15 @@ EasyFloat.with(this).setLayout(R.layout.float_test).show()

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

## 关于权限声明:
- 权限声明为非必须;
- **当使用到系统浮窗(`ShowPattern.ALL_TIME``ShowPattern.FOREGROUND`);**
- **当使用到系统浮窗(`ShowPattern.ALL_TIME``ShowPattern.FOREGROUND``ShowPattern.BACKROUND`);**
- 需要在`AndroidManifest.xml`进行权限声明。
```
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Expand All @@ -74,7 +74,7 @@ EasyFloat.init(this, isDebug)
EasyFloat.with(this)
// 设置浮窗xml布局文件,并可设置详细信息
.setLayout(R.layout.float_app, OnInvokeView { })
// 设置浮窗显示类型,默认只在当前Activity显示,可选一直显示、仅前台显示
// 设置浮窗显示类型,默认只在当前Activity显示,可选一直显示、仅前台显示、仅后台显示
.setShowPattern(ShowPattern.ALL_TIME)
// 设置吸附方式,共15种模式,详情参考SidePattern
.setSidePattern(SidePattern.RESULT_HORIZONTAL)
Expand Down
3 changes: 3 additions & 0 deletions UpdateDoc.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
## 版本更新日志
#### v 1.2.3:
- 新增仅后台显示(`ShowPattern.BACKGROUND`)。

#### v 1.2.2:
- 优化细节。

Expand Down
90 changes: 31 additions & 59 deletions easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -170,102 +170,76 @@ class EasyFloat {
// 创建浮窗数据类,方便管理配置
private val config = FloatConfig()

fun setSidePattern(sidePattern: SidePattern): Builder {
config.sidePattern = sidePattern
return this
}
fun setSidePattern(sidePattern: SidePattern): Builder =
this.apply { config.sidePattern = sidePattern }

fun setShowPattern(showPattern: ShowPattern): Builder {
config.showPattern = showPattern
return this
}
fun setShowPattern(showPattern: ShowPattern): Builder =
this.apply { config.showPattern = showPattern }

@JvmOverloads
fun setLayout(layoutId: Int, invokeView: OnInvokeView? = null): Builder {
fun setLayout(layoutId: Int, invokeView: OnInvokeView? = null): Builder = this.apply {
config.layoutId = layoutId
config.invokeView = invokeView
return this
}

@JvmOverloads
fun setGravity(gravity: Int, offsetX: Int = 0, offsetY: Int = 0): Builder {
fun setGravity(gravity: Int, offsetX: Int = 0, offsetY: Int = 0): Builder = this.apply {
config.gravity = gravity
config.offsetPair = Pair(offsetX, offsetY)
return this
}

fun setLocation(x: Int, y: Int): Builder {
config.locationPair = Pair(x, y)
return this
}
fun setLocation(x: Int, y: Int): Builder = this.apply { config.locationPair = Pair(x, y) }

fun setTag(floatTag: String?): Builder {
config.floatTag = floatTag
return this
}
fun setTag(floatTag: String?): Builder = this.apply { config.floatTag = floatTag }

fun setDragEnable(dragEnable: Boolean): Builder {
config.dragEnable = dragEnable
return this
}
fun setDragEnable(dragEnable: Boolean): Builder =
this.apply { config.dragEnable = dragEnable }

/**
* 该方法针对系统浮窗,单页面浮窗无需设置
*/
fun hasEditText(hasEditText: Boolean): Builder {
config.hasEditText = hasEditText
return this
}
fun hasEditText(hasEditText: Boolean): Builder =
this.apply { config.hasEditText = hasEditText }

@Deprecated("建议直接在 setLayout 设置详细布局")
fun invokeView(invokeView: OnInvokeView): Builder {
config.invokeView = invokeView
return this
}
fun invokeView(invokeView: OnInvokeView): Builder =
this.apply { config.invokeView = invokeView }

/**
* 通过传统接口,进行浮窗的各种状态回调
*/
fun registerCallbacks(callbacks: OnFloatCallbacks): Builder {
config.callbacks = callbacks
return this
}
fun registerCallbacks(callbacks: OnFloatCallbacks): Builder =
this.apply { config.callbacks = callbacks }

/**
* 针对kotlin 用户,传入带FloatCallbacks.Builder 返回值的 lambda,可按需回调
* 为了避免方法重载时 出现编译错误的情况,更改了方法名
*/
fun registerCallback(builder: FloatCallbacks.Builder.() -> Unit): Builder {
fun registerCallback(builder: FloatCallbacks.Builder.() -> Unit): Builder = this.apply {
config.floatCallbacks = FloatCallbacks().apply { registerListener(builder) }
return this
}

fun setAnimator(floatAnimator: OnFloatAnimator?): Builder {
config.floatAnimator = floatAnimator
return this
}
fun setAnimator(floatAnimator: OnFloatAnimator?): Builder =
this.apply { config.floatAnimator = floatAnimator }

fun setAppFloatAnimator(appFloatAnimator: OnAppFloatAnimator?): Builder {
config.appFloatAnimator = appFloatAnimator
return this
}
fun setAppFloatAnimator(appFloatAnimator: OnAppFloatAnimator?): Builder =
this.apply { config.appFloatAnimator = appFloatAnimator }

fun setMatchParent(widthMatch: Boolean = false, heightMatch: Boolean = false): Builder {
config.widthMatch = widthMatch
config.heightMatch = heightMatch
return this
}
fun setMatchParent(widthMatch: Boolean = false, heightMatch: Boolean = false): Builder =
this.apply {
config.widthMatch = widthMatch
config.heightMatch = heightMatch
}

// 设置需要过滤的Activity,仅对系统浮窗有效
fun setFilter(vararg clazz: Class<*>): Builder {
fun setFilter(vararg clazz: Class<*>): Builder = this.apply {
clazz.forEach {
config.filterSet.add(it.name)
if (it.name == activity.componentName.className) {
// 过滤掉当前Activity
config.filterSelf = true
}
}
return this
}

/**
Expand Down Expand Up @@ -303,12 +277,10 @@ class EasyFloat {
/**
* 申请浮窗权限的结果回调
*/
override fun permissionResult(isOpen: Boolean) {
if (isOpen) createAppFloat() else {
config.callbacks?.createdResult(false, "系统浮窗权限不足,开启失败", null)
config.floatCallbacks?.builder?.createdResult?.invoke(false, "系统浮窗权限不足,开启失败", null)
logger.w("系统浮窗权限不足,开启失败")
}
override fun permissionResult(isOpen: Boolean) = if (isOpen) createAppFloat() else {
config.callbacks?.createdResult(false, "系统浮窗权限不足,开启失败", null)
config.floatCallbacks?.builder?.createdResult?.invoke(false, "系统浮窗权限不足,开启失败", null)
logger.w("系统浮窗权限不足,开启失败")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ package com.lzf.easyfloat.enums
*/
enum class ShowPattern {

// 只在当前Activity显示、应用位于前台的时候显示、一直显示(不分前后台)
CURRENT_ACTIVITY, FOREGROUND, ALL_TIME
// 只在当前Activity显示、仅应用前台时显示、仅应用后台时显示,一直显示(不分前后台)
CURRENT_ACTIVITY, FOREGROUND, BACKGROUND, ALL_TIME
}
47 changes: 22 additions & 25 deletions easyfloat/src/main/java/com/lzf/easyfloat/utils/LifecycleUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,28 @@ internal object LifecycleUtils {
if (activity == null) return
activityCount++
FloatManager.floatMap.forEach { (tag, manager) ->
run {
// 如果手动隐藏浮窗,不再考虑过滤信息
if (!manager.config.needShow) return@run
// 过滤不需要显示浮窗的页面
manager.config.filterSet.forEach filterSet@{
if (it == activity.componentName.className) {
setVisible(false, tag)
manager.config.needShow = false
logger.i("过滤浮窗显示: $it, tag: $tag")
return@filterSet
}
}
// 仅后台显示模式下,隐藏浮窗
if (manager.config.showPattern == ShowPattern.BACKGROUND) {
setVisible(false, tag)
return
}

// 当过滤信息没有匹配上时,需要发送广播,反之修改needShow为默认值
if (manager.config.needShow) setVisible(tag = tag)
else manager.config.needShow = true
// 如果手动隐藏浮窗,不再考虑过滤信息
if (!manager.config.needShow) return

// 过滤不需要显示浮窗的页面
manager.config.filterSet.forEach filterSet@{
if (it == activity.componentName.className) {
setVisible(false, tag)
manager.config.needShow = false
logger.i("过滤浮窗显示: $it, tag: $tag")
return@filterSet
}
}

// 当过滤信息没有匹配上时,需要发送广播,反之修改needShow为默认值
if (manager.config.needShow) setVisible(tag = tag)
else manager.config.needShow = true
}
}

Expand All @@ -57,17 +62,9 @@ internal object LifecycleUtils {
if (activity == null) return
activityCount--
if (isForeground()) return
// 当app处于后台时,检测是否有仅前台显示的系统浮窗
FloatManager.floatMap.forEach { (tag, manager) ->
run {
// 如果手动隐藏浮窗,不再考虑过滤信息
if (!manager.config.needShow) return@run
when (manager.config.showPattern) {
ShowPattern.ALL_TIME -> setVisible(true, tag)
ShowPattern.FOREGROUND -> setVisible(tag = tag)
else -> return
}
}
// 当app处于后台时,不是仅前台显示的浮窗,都需要显示
setVisible(manager.config.showPattern != ShowPattern.FOREGROUND, tag)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.os.Build
import android.view.*
import com.lzf.easyfloat.anim.AppFloatAnimatorManager
import com.lzf.easyfloat.data.FloatConfig
import com.lzf.easyfloat.enums.ShowPattern
import com.lzf.easyfloat.interfaces.OnFloatTouchListener
import com.lzf.easyfloat.utils.DisplayUtils

Expand Down Expand Up @@ -75,6 +76,10 @@ internal class AppFloatManager(val context: Context, var config: FloatConfig) {
// 将浮窗布局文件添加到父容器frameLayout中,并返回该浮窗文件
val floatingView =
LayoutInflater.from(context).inflate(config.layoutId!!, frameLayout, true)
// 如果设置了过滤当前页,或者设置仅后台显示,设置视图不可见可以避免闪一下,不能直接设置GONE,否则定位会出现问题
if (config.filterSelf || config.showPattern == ShowPattern.BACKGROUND) {
floatingView.visibility = View.INVISIBLE
}
// 将frameLayout添加到系统windowManager中
windowManager.addView(frameLayout, params)

Expand All @@ -88,7 +93,9 @@ internal class AppFloatManager(val context: Context, var config: FloatConfig) {
frameLayout?.layoutListener = object : ParentFrameLayout.OnLayoutListener {
override fun onLayout() {
setGravity(frameLayout)
if (config.filterSelf) setVisible(View.GONE) else enterAnim()
// 如果设置了过滤当前页,或者设置仅后台显示,隐藏浮窗,否则执行入场动画
if (config.filterSelf || config.showPattern == ShowPattern.BACKGROUND)
setVisible(View.GONE) else enterAnim()
}
}

Expand Down
Binary file modified example/release/EasyFloat.apk
Binary file not shown.
4 changes: 3 additions & 1 deletion example/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".activity.MainActivity">
<activity
android:name=".activity.MainActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down

0 comments on commit d64c003

Please sign in to comment.