diff --git a/README.md b/README.md index 99973a7..3025f93 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ allprojects { - **在应用模块的`build.gradle`添加:** ``` dependencies { - implementation 'com.github.princekin-f:EasyFloat:1.3.1' + implementation 'com.github.princekin-f:EasyFloat:1.3.2' } ``` diff --git a/UpdateDoc.md b/UpdateDoc.md index 14965b0..d986afb 100644 --- a/UpdateDoc.md +++ b/UpdateDoc.md @@ -1,4 +1,7 @@ ## 版本更新日志 +#### v 1.3.2: +- 优化细节。 + #### v 1.3.1: - 优化`createdResult`回调。 diff --git a/build.gradle b/build.gradle index 26adab7..6c08101 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.41' + ext.kotlin_version = '1.3.71' repositories { google() jcenter() diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt index 0ff0368..3e815e5 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt @@ -18,6 +18,7 @@ import java.lang.ref.WeakReference /** * @author: liuzhenfeng + * @github:https://github.com/princekin-f * @function: 悬浮窗使用工具类 * @date: 2019-06-27 15:22 */ @@ -79,10 +80,8 @@ class EasyFloat { /** * 获取Activity浮窗管理类 */ - private fun manager(activity: Activity?): ActivityFloatManager? { - val a: Activity? = activity ?: activityWr?.get() - return a?.run { ActivityFloatManager(this) } - } + private fun manager(activity: Activity?) = + (activity ?: activityWr?.get())?.run { ActivityFloatManager(this) } // *************************** 以下系统浮窗的相关方法 *************************** /** @@ -104,7 +103,7 @@ class EasyFloat { */ @JvmStatic @JvmOverloads - fun showAppFloat(tag: String? = null) = FloatManager.visible(true, tag) + fun showAppFloat(tag: String? = null) = FloatManager.visible(true, tag, true) /** * 设置系统浮窗是否可拖拽,先获取浮窗的config,后修改相应属性 @@ -134,31 +133,33 @@ class EasyFloat { @JvmStatic @JvmOverloads fun filterActivity(activity: Activity, tag: String? = null) = - getConfig(tag).let { it?.filterSet?.add(activity.componentName.className) } + getFilterSet(tag)?.add(activity.componentName.className) @JvmStatic @JvmOverloads fun filterActivities(tag: String? = null, vararg clazz: Class<*>) = - clazz.forEach { c -> getConfig(tag).let { it?.filterSet?.add(c.name) } } + getFilterSet(tag)?.addAll(clazz.map { it.name }) @JvmStatic @JvmOverloads fun removeFilter(activity: Activity, tag: String? = null) = - getConfig(tag).let { it?.filterSet?.remove(activity.componentName.className) } + getFilterSet(tag)?.remove(activity.componentName.className) @JvmStatic @JvmOverloads fun removeFilters(tag: String? = null, vararg clazz: Class<*>) = - clazz.forEach { c -> getConfig(tag).let { it?.filterSet?.remove(c.name) } } + getFilterSet(tag)?.removeAll(clazz.map { it.name }) @JvmStatic @JvmOverloads - fun clearFilters(tag: String? = null) = getConfig(tag)?.filterSet?.clear() + fun clearFilters(tag: String? = null) = getFilterSet(tag)?.clear() /** * 获取系统浮窗的config */ private fun getConfig(tag: String?) = FloatManager.getAppFloatManager(tag)?.config + + private fun getFilterSet(tag: String?) = getConfig(tag)?.filterSet } @@ -170,65 +171,61 @@ class EasyFloat { // 创建浮窗数据类,方便管理配置 private val config = FloatConfig() - fun setSidePattern(sidePattern: SidePattern) = - this.apply { config.sidePattern = sidePattern } + fun setSidePattern(sidePattern: SidePattern) = apply { config.sidePattern = sidePattern } - fun setShowPattern(showPattern: ShowPattern) = - this.apply { config.showPattern = showPattern } + fun setShowPattern(showPattern: ShowPattern) = apply { config.showPattern = showPattern } @JvmOverloads - fun setLayout(layoutId: Int, invokeView: OnInvokeView? = null) = this.apply { + fun setLayout(layoutId: Int, invokeView: OnInvokeView? = null) = apply { config.layoutId = layoutId config.invokeView = invokeView } @JvmOverloads - fun setGravity(gravity: Int, offsetX: Int = 0, offsetY: Int = 0) = this.apply { + fun setGravity(gravity: Int, offsetX: Int = 0, offsetY: Int = 0) = apply { config.gravity = gravity config.offsetPair = Pair(offsetX, offsetY) } - fun setLocation(x: Int, y: Int) = this.apply { config.locationPair = Pair(x, y) } + fun setLocation(x: Int, y: Int) = apply { config.locationPair = Pair(x, y) } - fun setTag(floatTag: String?) = this.apply { config.floatTag = floatTag } + fun setTag(floatTag: String?) = apply { config.floatTag = floatTag } - fun setDragEnable(dragEnable: Boolean) = this.apply { config.dragEnable = dragEnable } + fun setDragEnable(dragEnable: Boolean) = apply { config.dragEnable = dragEnable } /** * 该方法针对系统浮窗,单页面浮窗无需设置 */ - fun hasEditText(hasEditText: Boolean) = this.apply { config.hasEditText = hasEditText } + fun hasEditText(hasEditText: Boolean) = apply { config.hasEditText = hasEditText } @Deprecated("建议直接在 setLayout 设置详细布局") - fun invokeView(invokeView: OnInvokeView) = this.apply { config.invokeView = invokeView } + fun invokeView(invokeView: OnInvokeView) = apply { config.invokeView = invokeView } /** * 通过传统接口,进行浮窗的各种状态回调 */ - fun registerCallbacks(callbacks: OnFloatCallbacks) = - this.apply { config.callbacks = callbacks } + fun registerCallbacks(callbacks: OnFloatCallbacks) = apply { config.callbacks = callbacks } /** * 针对kotlin 用户,传入带FloatCallbacks.Builder 返回值的 lambda,可按需回调 * 为了避免方法重载时 出现编译错误的情况,更改了方法名 */ - fun registerCallback(builder: FloatCallbacks.Builder.() -> Unit): Builder = this.apply { - config.floatCallbacks = FloatCallbacks().apply { registerListener(builder) } - } + fun registerCallback(builder: FloatCallbacks.Builder.() -> Unit) = + apply { config.floatCallbacks = FloatCallbacks().apply { registerListener(builder) } } fun setAnimator(floatAnimator: OnFloatAnimator?) = - this.apply { config.floatAnimator = floatAnimator } + apply { config.floatAnimator = floatAnimator } fun setAppFloatAnimator(appFloatAnimator: OnAppFloatAnimator?) = - this.apply { config.appFloatAnimator = appFloatAnimator } + apply { config.appFloatAnimator = appFloatAnimator } /** * 设置屏幕的有效显示高度(不包含虚拟导航栏的高度) */ fun setDisplayHeight(displayHeight: OnDisplayHeight) = - this.apply { config.displayHeight = displayHeight } + apply { config.displayHeight = displayHeight } - fun setMatchParent(widthMatch: Boolean = false, heightMatch: Boolean = false) = this.apply { + fun setMatchParent(widthMatch: Boolean = false, heightMatch: Boolean = false) = apply { config.widthMatch = widthMatch config.heightMatch = heightMatch } @@ -236,7 +233,7 @@ class EasyFloat { /** * 设置需要过滤的Activity,仅对系统浮窗有效 */ - fun setFilter(vararg clazz: Class<*>) = this.apply { + fun setFilter(vararg clazz: Class<*>) = apply { clazz.forEach { config.filterSet.add(it.name) // 过滤掉当前Activity @@ -255,9 +252,9 @@ class EasyFloat { // 申请浮窗权限 else -> PermissionUtils.requestPermission(activity, this) } else { - config.callbacks?.createdResult(false, "未设置浮窗布局文件", null) - config.floatCallbacks?.builder?.createdResult?.invoke(false, "未设置浮窗布局文件", null) - Logger.w("未设置浮窗布局文件") + config.callbacks?.createdResult(false, WARN_NO_LAYOUT, null) + config.floatCallbacks?.builder?.createdResult?.invoke(false, WARN_NO_LAYOUT, null) + Logger.w(WARN_NO_LAYOUT) } /** @@ -274,9 +271,9 @@ 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("系统浮窗权限不足,开启失败") + config.callbacks?.createdResult(false, WARN_PERMISSION, null) + config.floatCallbacks?.builder?.createdResult?.invoke(false, WARN_PERMISSION, null) + Logger.w(WARN_PERMISSION) } } diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatMessage.kt b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatMessage.kt new file mode 100644 index 0000000..120bad8 --- /dev/null +++ b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatMessage.kt @@ -0,0 +1,11 @@ +package com.lzf.easyfloat + +/** + * @author: liuzhenfeng + * @github:https://github.com/princekin-f + * @function: + * @date: 2020/4/10 14:25 + */ +const val WARN_PERMISSION = "系统浮窗权限不足,开启失败" +const val WARN_NO_LAYOUT = "未设置浮窗布局文件" +const val WARN_REPEATED_TAG = "请为系统浮窗设置不同的tag" \ No newline at end of file diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/anim/AppFloatDefaultAnimator.kt b/easyfloat/src/main/java/com/lzf/easyfloat/anim/AppFloatDefaultAnimator.kt index 54df2fe..006d01b 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/anim/AppFloatDefaultAnimator.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/anim/AppFloatDefaultAnimator.kt @@ -20,14 +20,12 @@ open class AppFloatDefaultAnimator : OnAppFloatAnimator { params: WindowManager.LayoutParams, windowManager: WindowManager, sidePattern: SidePattern - ): Animator? { - val value = initValue(view, params, windowManager) - val animator = ValueAnimator.ofInt(value, params.x).setDuration(500) - animator.addUpdateListener { + ): Animator? = ValueAnimator.ofInt(initValue(view, params, windowManager), params.x).apply { + duration = 500 + addUpdateListener { params.x = it.animatedValue as Int windowManager.updateViewLayout(view, params) } - return animator } override fun exitAnim( @@ -35,14 +33,11 @@ open class AppFloatDefaultAnimator : OnAppFloatAnimator { params: WindowManager.LayoutParams, windowManager: WindowManager, sidePattern: SidePattern - ): Animator? { - val value = initValue(view, params, windowManager) - val animator = ValueAnimator.ofInt(params.x, value).setDuration(500) - animator.addUpdateListener { + ): Animator? = ValueAnimator.ofInt(params.x, initValue(view, params, windowManager)).apply { + addUpdateListener { params.x = it.animatedValue as Int windowManager.updateViewLayout(view, params) } - return animator } private fun initValue( diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/utils/LifecycleUtils.kt b/easyfloat/src/main/java/com/lzf/easyfloat/utils/LifecycleUtils.kt index a39ede1..c8166d8 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/utils/LifecycleUtils.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/utils/LifecycleUtils.kt @@ -54,13 +54,13 @@ internal object LifecycleUtils { private fun checkShow(activity: Activity?) { if (activity == null) return FloatManager.floatMap.forEach { (tag, manager) -> - when { - // 仅后台显示模式下,隐藏浮窗 - manager.config.showPattern == ShowPattern.BACKGROUND -> setVisible(false, tag) - // 如果没有手动隐藏浮窗,需要考虑过滤信息 - manager.config.needShow -> setVisible( - !manager.config.filterSet.contains(activity.componentName.className), tag - ) + manager.config.apply { + when { + // 仅后台显示模式下,隐藏浮窗 + showPattern == ShowPattern.BACKGROUND -> setVisible(false, tag) + // 如果没有手动隐藏浮窗,需要考虑过滤信息 + needShow -> setVisible(!filterSet.contains(activity.componentName.className), tag) + } } } } @@ -71,12 +71,14 @@ internal object LifecycleUtils { private fun checkHide() { if (isForeground()) return FloatManager.floatMap.forEach { (tag, manager) -> - // 当app处于后台时,不是仅前台显示的浮窗,都需要显示 - setVisible(manager.config.showPattern != ShowPattern.FOREGROUND, tag) + manager.config.apply { + // 当app处于后台时,不是仅前台显示的浮窗,如果没有手动隐藏,都需要显示 + setVisible(showPattern != ShowPattern.FOREGROUND && needShow, tag) + } } } - private fun isForeground() = activityCount > 0 + fun isForeground() = activityCount > 0 private fun setVisible(isShow: Boolean = isForeground(), tag: String?) = FloatManager.visible(isShow, tag) diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/widget/appfloat/AppFloatManager.kt b/easyfloat/src/main/java/com/lzf/easyfloat/widget/appfloat/AppFloatManager.kt index 36310bd..337f05c 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/widget/appfloat/AppFloatManager.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/widget/appfloat/AppFloatManager.kt @@ -13,6 +13,7 @@ import com.lzf.easyfloat.data.FloatConfig import com.lzf.easyfloat.enums.ShowPattern import com.lzf.easyfloat.interfaces.OnFloatTouchListener import com.lzf.easyfloat.utils.DisplayUtils +import com.lzf.easyfloat.utils.LifecycleUtils import com.lzf.easyfloat.utils.Logger /** @@ -89,9 +90,11 @@ internal class AppFloatManager(val context: Context, var config: FloatConfig) { frameLayout?.layoutListener = object : ParentFrameLayout.OnLayoutListener { override fun onLayout() { setGravity(frameLayout) - // 如果设置了过滤当前页,或者设置仅后台显示,隐藏浮窗,否则执行入场动画 - if (config.filterSelf || config.showPattern == ShowPattern.BACKGROUND) - setVisible(View.GONE) else enterAnim(floatingView) + // 如果设置了过滤当前页,或者设置仅后台显示,或者在后台创建前台浮窗。隐藏浮窗,否则执行入场动画 + if (config.filterSelf + || config.showPattern == ShowPattern.BACKGROUND + || (config.showPattern == ShowPattern.FOREGROUND && !LifecycleUtils.isForeground()) + ) setVisible(View.GONE) else enterAnim(floatingView) // 设置callbacks config.layoutView = floatingView @@ -244,7 +247,7 @@ internal class AppFloatManager(val context: Context, var config: FloatConfig) { } /** - * 退出动画执行结束/没有退出动画,一些回调、移除、检测是否需要关闭Service等操作 + * 退出动画执行结束/没有退出动画,进行回调、移除等操作 */ private fun floatOver() = try { config.isAnim = false diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/widget/appfloat/FloatManager.kt b/easyfloat/src/main/java/com/lzf/easyfloat/widget/appfloat/FloatManager.kt index f9aa7af..45504b9 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/widget/appfloat/FloatManager.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/widget/appfloat/FloatManager.kt @@ -2,6 +2,7 @@ package com.lzf.easyfloat.widget.appfloat import android.content.Context import android.view.View +import com.lzf.easyfloat.WARN_REPEATED_TAG import com.lzf.easyfloat.data.FloatConfig import com.lzf.easyfloat.utils.Logger @@ -23,15 +24,18 @@ internal object FloatManager { floatMap[config.floatTag!!] = AppFloatManager(context.applicationContext, config) .apply { createFloat() } } else { - config.callbacks?.createdResult(false, "请为系统浮窗设置不同的tag", null) - Logger.w("请为系统浮窗设置不同的tag") + config.callbacks?.createdResult(false, WARN_REPEATED_TAG, null) + Logger.w(WARN_REPEATED_TAG) } /** * 设置浮窗的显隐,用户主动调用隐藏时,needShow需要为false */ - fun visible(isShow: Boolean, tag: String? = null, needShow: Boolean = true) = - floatMap[getTag(tag)]?.setVisible(if (isShow) View.VISIBLE else View.GONE, needShow) + fun visible( + isShow: Boolean, + tag: String? = null, + needShow: Boolean = floatMap[tag]?.config?.needShow ?: true + ) = floatMap[getTag(tag)]?.setVisible(if (isShow) View.VISIBLE else View.GONE, needShow) /** * 关闭浮窗,执行浮窗的退出动画 diff --git a/example/release/EasyFloat.apk b/example/release/EasyFloat.apk index 396e64b..fd2d9bb 100644 Binary files a/example/release/EasyFloat.apk and b/example/release/EasyFloat.apk differ diff --git a/example/src/main/java/com/lzf/easyfloat/example/MyAdapter.kt b/example/src/main/java/com/lzf/easyfloat/example/MyAdapter.kt new file mode 100644 index 0000000..e2bb221 --- /dev/null +++ b/example/src/main/java/com/lzf/easyfloat/example/MyAdapter.kt @@ -0,0 +1,43 @@ +package com.lzf.easyfloat.example + +import android.annotation.SuppressLint +import android.content.Context +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.CheckBox +import android.widget.TextView +import com.lzf.easyfloat.EasyFloat + +/** + * @author: liuzhenfeng + * @github:https://github.com/princekin-f + * @function: + * @date: 2020/4/16 13:57 + */ +class MyAdapter(context: Context, private val stringArray: Array) : + ArrayAdapter(context, R.layout.item_simple_list, stringArray) { + + @SuppressLint("ViewHolder") + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val view = LayoutInflater.from(context).inflate(R.layout.item_simple_list, null) + view.findViewById(R.id.tv_item).text = stringArray[position] + view.findViewById(R.id.checkbox).apply { + setOnTouchListener { _, event -> + logger.e("setOnTouchListener: ${event.action}") + EasyFloat.appFloatDragEnable(event?.action == MotionEvent.ACTION_CANCEL) + false + } + + setOnCheckedChangeListener { _, isChecked -> + logger.e("点击了:$position isChecked:$isChecked") + } + } +// view.setOnClickListener { +// logger.e("点击了item: $position") +// } + return view + } +} \ No newline at end of file diff --git a/example/src/main/java/com/lzf/easyfloat/example/activity/MainActivity.kt b/example/src/main/java/com/lzf/easyfloat/example/activity/MainActivity.kt index 71e11b6..2e927da 100644 --- a/example/src/main/java/com/lzf/easyfloat/example/activity/MainActivity.kt +++ b/example/src/main/java/com/lzf/easyfloat/example/activity/MainActivity.kt @@ -194,14 +194,14 @@ class MainActivity : AppCompatActivity(), View.OnClickListener { // // 解决 ListView 拖拽滑动冲突 // it.findViewById(R.id.lv_test).apply { -// adapter = ArrayAdapter( -// this@MainActivity, R.layout.item_simple_list, +// adapter = MyAdapter( +// this@MainActivity, // arrayOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "...") // ) // // // 监听 ListView 的触摸事件,手指触摸时关闭拖拽,手指离开重新开启拖拽 // setOnTouchListener { _, event -> -// logger.e(event.action) +// logger.e("listView: ${event.action}") // EasyFloat.appFloatDragEnable(event?.action == MotionEvent.ACTION_UP) // false // } diff --git a/example/src/main/res/layout/item_simple_list.xml b/example/src/main/res/layout/item_simple_list.xml index 391204a..c3c7dec 100644 --- a/example/src/main/res/layout/item_simple_list.xml +++ b/example/src/main/res/layout/item_simple_list.xml @@ -1,12 +1,21 @@ - + android:background="@color/green"> - \ No newline at end of file + + + + + \ No newline at end of file