diff --git a/README.md b/README.md index 833eba7..6f66ad5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ## EasyFloat:Android悬浮窗框架 -[![](https://jitpack.io/v/mr-bogey/EasyFloat.svg)](https://jitpack.io/#mr-bogey/EasyFloat) +[![](https://jitpack.io/v/princekin-f/EasyFloat.svg)](https://jitpack.io/#princekin-f/EasyFloat) [![License](https://img.shields.io/badge/License%20-Apache%202-337ab7.svg)](https://www.apache.org/licenses/LICENSE-2.0) > [EasyFloat:浮窗从未如此简单](https://www.jianshu.com/p/7d1a7c82094a) @@ -44,7 +44,7 @@ allprojects { - **在应用模块的`build.gradle`添加:** ``` dependencies { - implementation 'com.github.princekin-f:EasyFloat:2.0.3' + implementation 'com.github.princekin-f:EasyFloat:2.0.4' } ``` @@ -161,8 +161,8 @@ isShow(tag: String? = null) // 获取我们设置的浮窗View getFloatView(tag: String? = null) -// 更新浮窗坐标,未指定坐标执行吸附动画 -updateFloat(tag: String? = null, x: Int = -1, y: Int = -1) +// 更新浮窗位置、大小信息,未指定数值执行吸附动画 +updateFloat(tag: String? = null, x: Int = -1, y: Int = -1, width: Int = -1, height: Int = -1) // ******************* 系统浮窗独有 ******************* // 添加单个浮窗过滤页面 diff --git a/build.gradle b/build.gradle index d0ff424..9ef6059 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.4.20' + ext.kotlin_version = '1.5.31' repositories { google() jcenter() maven { url "https://jitpack.io" } } dependencies { - classpath 'com.android.tools.build:gradle:4.1.1' + classpath 'com.android.tools.build:gradle:4.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' // NOTE: Do not place your application dependencies here; they belong diff --git a/easyfloat/build.gradle b/easyfloat/build.gradle index a869546..7547517 100644 --- a/easyfloat/build.gradle +++ b/easyfloat/build.gradle @@ -5,13 +5,16 @@ apply plugin: 'com.github.dcendents.android-maven' group = 'com.github.princekin-f' android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { minSdkVersion 17 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" + + // aar 打包混淆配置 + consumerProguardFiles "proguard-rules.pro" } buildTypes { diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt index 3722078..d4e2d8c 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt @@ -28,8 +28,8 @@ class EasyFloat { /** * 通过上下文,创建浮窗的构建者信息,使浮窗拥有一些默认属性 - * @param activity 上下文信息,优先使用Activity上下文,因为系统浮窗权限的自动申请,需要使用Activity信息 - * @return 浮窗属性构建者 + * @param activity 上下文信息,优先使用Activity上下文,因为系统浮窗权限的自动申请,需要使用Activity信息 + * @return 浮窗属性构建者 */ @JvmStatic fun with(activity: Context): Builder = if (activity is Activity) Builder(activity) @@ -37,8 +37,8 @@ class EasyFloat { /** * 关闭当前浮窗 - * @param tag 浮窗标签 - * @param force 立即关闭,有退出动画也不执行 + * @param tag 浮窗标签 + * @param force 立即关闭,有退出动画也不执行 */ @JvmStatic @JvmOverloads @@ -47,7 +47,7 @@ class EasyFloat { /** * 隐藏当前浮窗 - * @param tag 浮窗标签 + * @param tag 浮窗标签 */ @JvmStatic @JvmOverloads @@ -55,7 +55,7 @@ class EasyFloat { /** * 设置当前浮窗可见 - * @param tag 浮窗标签 + * @param tag 浮窗标签 */ @JvmStatic @JvmOverloads @@ -63,8 +63,8 @@ class EasyFloat { /** * 设置当前浮窗是否可拖拽,先获取浮窗的config,后修改相应属性 - * @param dragEnable 是否可拖拽 - * @param tag 浮窗标签 + * @param dragEnable 是否可拖拽 + * @param tag 浮窗标签 */ @JvmStatic @JvmOverloads @@ -73,8 +73,8 @@ class EasyFloat { /** * 获取当前浮窗是否显示,通过浮窗的config,获取显示状态 - * @param tag 浮窗标签 - * @return 当前浮窗是否显示 + * @param tag 浮窗标签 + * @return 当前浮窗是否显示 */ @JvmStatic @JvmOverloads @@ -82,28 +82,36 @@ class EasyFloat { /** * 获取当前浮窗中,我们传入的View - * @param tag 浮窗标签 + * @param tag 浮窗标签 */ @JvmStatic @JvmOverloads fun getFloatView(tag: String? = null): View? = getConfig(tag)?.layoutView /** - * 更新浮窗坐标,未指定坐标执行吸附动画 - * @param tag 浮窗标签 - * @param x 更新后的X轴坐标 - * @param y 更新后的Y轴坐标 + * 更新浮窗坐标、以及大小,未指定数值(全为-1)执行吸附动画; + * 需要修改的参数,传入具体数值,不需要修改的参数保持-1即可 + * @param tag 浮窗标签 + * @param x 更新后的X轴坐标 + * @param y 更新后的Y轴坐标 + * @param width 更新后的宽度 + * @param height 更新后的高度 */ @JvmStatic @JvmOverloads - fun updateFloat(tag: String? = null, x: Int = -1, y: Int = -1) = - FloatingWindowManager.getHelper(tag)?.updateFloat(x, y) + fun updateFloat( + tag: String? = null, + x: Int = -1, + y: Int = -1, + width: Int = -1, + height: Int = -1 + ) = FloatingWindowManager.getHelper(tag)?.updateFloat(x, y, width, height) // 以下几个方法为:系统浮窗过滤页面的添加、移除、清空 /** * 为当前浮窗过滤,设置需要过滤的Activity - * @param activity 需要过滤的Activity - * @param tag 浮窗标签 + * @param activity 需要过滤的Activity + * @param tag 浮窗标签 */ @JvmStatic @JvmOverloads @@ -112,8 +120,8 @@ class EasyFloat { /** * 为当前浮窗,设置需要过滤的Activity类名(一个或者多个) - * @param tag 浮窗标签 - * @param clazz 需要过滤的Activity类名,一个或者多个 + * @param tag 浮窗标签 + * @param clazz 需要过滤的Activity类名,一个或者多个 */ @JvmStatic @JvmOverloads @@ -122,8 +130,8 @@ class EasyFloat { /** * 为当前浮窗,移除需要过滤的Activity - * @param activity 需要移除过滤的Activity - * @param tag 浮窗标签 + * @param activity 需要移除过滤的Activity + * @param tag 浮窗标签 */ @JvmStatic @JvmOverloads @@ -132,8 +140,8 @@ class EasyFloat { /** * 为当前浮窗,移除需要过滤的Activity类名(一个或者多个) - * @param tag 浮窗标签 - * @param clazz 需要移除过滤的Activity类名,一个或者多个 + * @param tag 浮窗标签 + * @param clazz 需要移除过滤的Activity类名,一个或者多个 */ @JvmStatic @JvmOverloads @@ -142,7 +150,7 @@ class EasyFloat { /** * 清除当前浮窗的所有过滤信息 - * @param tag 浮窗标签 + * @param tag 浮窗标签 */ @JvmStatic @JvmOverloads @@ -150,13 +158,13 @@ class EasyFloat { /** * 获取当前浮窗的config - * @param tag 浮窗标签 + * @param tag 浮窗标签 */ private fun getConfig(tag: String?) = FloatingWindowManager.getHelper(tag)?.config /** * 获取当前浮窗的过滤集合 - * @param tag 浮窗标签 + * @param tag 浮窗标签 */ private fun getFilterSet(tag: String?) = getConfig(tag)?.filterSet } @@ -172,20 +180,20 @@ class EasyFloat { /** * 设置浮窗的吸附模式 - * @param sidePattern 浮窗吸附模式 + * @param sidePattern 浮窗吸附模式 */ fun setSidePattern(sidePattern: SidePattern) = apply { config.sidePattern = sidePattern } /** * 设置浮窗的显示模式 - * @param showPattern 浮窗显示模式 + * @param showPattern 浮窗显示模式 */ fun setShowPattern(showPattern: ShowPattern) = apply { config.showPattern = showPattern } /** * 设置浮窗的布局文件,以及布局的操作接口 - * @param layoutId 布局文件的资源Id - * @param invokeView 布局文件的操作接口 + * @param layoutId 布局文件的资源Id + * @param invokeView 布局文件的操作接口 */ @JvmOverloads fun setLayout(layoutId: Int, invokeView: OnInvokeView? = null) = apply { @@ -195,8 +203,8 @@ class EasyFloat { /** * 设置浮窗的布局视图,以及布局的操作接口 - * @param layoutView 自定义的布局视图 - * @param invokeView 布局视图的操作接口 + * @param layoutView 自定义的布局视图 + * @param invokeView 布局视图的操作接口 */ @JvmOverloads fun setLayout(layoutView: View, invokeView: OnInvokeView? = null) = apply { @@ -206,9 +214,9 @@ class EasyFloat { /** * 设置浮窗的对齐方式,以及偏移量 - * @param gravity 对齐方式 - * @param offsetX 目标坐标的水平偏移量 - * @param offsetY 目标坐标的竖直偏移量 + * @param gravity 对齐方式 + * @param offsetX 目标坐标的水平偏移量 + * @param offsetY 目标坐标的竖直偏移量 */ @JvmOverloads fun setGravity(gravity: Int, offsetX: Int = 0, offsetY: Int = 0) = apply { @@ -220,7 +228,7 @@ class EasyFloat { * 当layout大小变化后,整体view的位置的对齐方式 * 比如,当设置为 Gravity.END 时,当view的宽度变小或者变大时,都将会以原有的右边对齐
* 默认对齐方式为左上角 - * @param gravity 对齐方式 + * @param gravity 对齐方式 */ fun setLayoutChangedGravity(gravity: Int) = apply { config.layoutChangedGravity = gravity; @@ -228,17 +236,17 @@ class EasyFloat { /** * 设置浮窗的起始坐标,优先级高于setGravity - * @param x 起始水平坐标 - * @param y 起始竖直坐标 + * @param x 起始水平坐标 + * @param y 起始竖直坐标 */ fun setLocation(x: Int, y: Int) = apply { config.locationPair = Pair(x, y) } /** * 设置浮窗的拖拽边距值 - * @param left 浮窗左侧边距 - * @param top 浮窗顶部边距 - * @param right 浮窗右侧边距 - * @param bottom 浮窗底部边距 + * @param left 浮窗左侧边距 + * @param top 浮窗顶部边距 + * @param right 浮窗右侧边距 + * @param bottom 浮窗底部边距 */ @JvmOverloads fun setBorder( @@ -256,61 +264,61 @@ class EasyFloat { /** * 设置浮窗的标签:只有一个浮窗时,可以不设置; * 有多个浮窗必须设置不容的浮窗,不然没法管理,所以禁止创建相同标签的浮窗 - * @param floatTag 浮窗标签 + * @param floatTag 浮窗标签 */ fun setTag(floatTag: String?) = apply { config.floatTag = floatTag } /** * 设置浮窗是否可拖拽 - * @param dragEnable 是否可拖拽 + * @param dragEnable 是否可拖拽 */ fun setDragEnable(dragEnable: Boolean) = apply { config.dragEnable = dragEnable } /** * 设置浮窗是否状态栏沉浸 - * @param immersionStatusBar 是否状态栏沉浸 + * @param immersionStatusBar 是否状态栏沉浸 */ fun setImmersionStatusBar(immersionStatusBar: Boolean) = apply { config.immersionStatusBar = immersionStatusBar } /** * 浮窗是否包含EditText,浮窗默认不获取焦点,无法弹起软键盘,所以需要适配 - * @param hasEditText 是否包含EditText + * @param hasEditText 是否包含EditText */ fun hasEditText(hasEditText: Boolean) = apply { config.hasEditText = hasEditText } /** * 通过传统接口,进行浮窗的各种状态回调 - * @param callbacks 浮窗的各种事件回调 + * @param callbacks 浮窗的各种事件回调 */ fun registerCallbacks(callbacks: OnFloatCallbacks) = apply { config.callbacks = callbacks } /** * 针对kotlin 用户,传入带FloatCallbacks.Builder 返回值的 lambda,可按需回调 * 为了避免方法重载时 出现编译错误的情况,更改了方法名 - * @param builder 事件回调的构建者 + * @param builder 事件回调的构建者 */ fun registerCallback(builder: FloatCallbacks.Builder.() -> Unit) = apply { config.floatCallbacks = FloatCallbacks().apply { registerListener(builder) } } /** * 设置浮窗的出入动画 - * @param floatAnimator 浮窗的出入动画,为空时不执行动画 + * @param floatAnimator 浮窗的出入动画,为空时不执行动画 */ fun setAnimator(floatAnimator: OnFloatAnimator?) = apply { config.floatAnimator = floatAnimator } /** * 设置屏幕的有效显示高度(不包含虚拟导航栏的高度) - * @param displayHeight 屏幕的有效高度 + * @param displayHeight 屏幕的有效高度 */ fun setDisplayHeight(displayHeight: OnDisplayHeight) = apply { config.displayHeight = displayHeight } /** * 设置浮窗宽高是否充满屏幕 - * @param widthMatch 宽度是否充满屏幕 - * @param heightMatch 高度是否充满屏幕 + * @param widthMatch 宽度是否充满屏幕 + * @param heightMatch 高度是否充满屏幕 */ fun setMatchParent(widthMatch: Boolean = false, heightMatch: Boolean = false) = apply { config.widthMatch = widthMatch @@ -319,7 +327,7 @@ class EasyFloat { /** * 设置需要过滤的Activity类名,仅对系统浮窗有效 - * @param clazz 需要过滤的Activity类名 + * @param clazz 需要过滤的Activity类名 */ fun setFilter(vararg clazz: Class<*>) = apply { clazz.forEach { @@ -360,14 +368,14 @@ class EasyFloat { /** * 申请浮窗权限的结果回调 - * @param isOpen 悬浮窗权限是否打开 + * @param isOpen 悬浮窗权限是否打开 */ override fun permissionResult(isOpen: Boolean) = if (isOpen) createFloat() else callbackCreateFailed(WARN_PERMISSION) /** * 回调创建失败 - * @param reason 失败原因 + * @param reason 失败原因 */ private fun callbackCreateFailed(reason: String) { config.callbacks?.createdResult(false, reason, null) diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatInitializer.kt b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatInitializer.kt index 2df6f95..0398f2f 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatInitializer.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatInitializer.kt @@ -10,7 +10,7 @@ import com.lzf.easyfloat.utils.LifecycleUtils /** * @author: liuzhenfeng * @github:https://github.com/princekin-f - * @function: + * @function: 通过内容提供者的上下文,进行生命周期回调的初始化 * @date: 2020/10/23 13:41 */ class EasyFloatInitializer : ContentProvider() { diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatMessage.kt b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatMessage.kt index c1c173a..f9599b3 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatMessage.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/EasyFloatMessage.kt @@ -3,7 +3,7 @@ package com.lzf.easyfloat /** * @author: liuzhenfeng * @github:https://github.com/princekin-f - * @function: + * @function: 创建失败提示信息 * @date: 2020/4/10 14:25 */ const val WARN_PERMISSION = "No permission exception. You need to turn on overlay permissions." @@ -11,4 +11,5 @@ const val WARN_NO_LAYOUT = "No layout exception. You need to set up the layout f const val WARN_UNINITIALIZED = "Uninitialized exception. You need to initialize in the application." const val WARN_REPEATED_TAG = "Tag exception. You need to set different EasyFloat tag." const val WARN_CONTEXT_ACTIVITY = "Context exception. Activity float need to pass in a activity context." -const val WARN_CONTEXT_REQUEST = "Context exception. Request Permission need to pass in a activity context." \ No newline at end of file +const val WARN_CONTEXT_REQUEST = "Context exception. Request Permission need to pass in a activity context." +const val WARN_ACTIVITY_NULL = "Activity is null." \ No newline at end of file diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/core/FloatingWindowHelper.kt b/easyfloat/src/main/java/com/lzf/easyfloat/core/FloatingWindowHelper.kt index 2b0f486..b5eda5e 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/core/FloatingWindowHelper.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/core/FloatingWindowHelper.kt @@ -12,6 +12,7 @@ import android.os.IBinder import android.view.* import android.view.WindowManager.LayoutParams.* import android.widget.EditText +import com.lzf.easyfloat.WARN_ACTIVITY_NULL import com.lzf.easyfloat.anim.AnimatorManager import com.lzf.easyfloat.data.FloatConfig import com.lzf.easyfloat.enums.ShowPattern @@ -25,10 +26,14 @@ import com.lzf.easyfloat.widget.ParentFrameLayout /** * @author: Liuzhenfeng * @date: 12/1/20 23:40 - * @Description: + * @Description: 负责具体悬浮窗的创建管理 */ internal class FloatingWindowHelper(val context: Context, var config: FloatConfig) { + interface CreateCallback { + fun onCreate(success: Boolean) + } + lateinit var windowManager: WindowManager lateinit var params: WindowManager.LayoutParams var frameLayout: ParentFrameLayout? = null @@ -37,11 +42,17 @@ internal class FloatingWindowHelper(val context: Context, var config: FloatConfi private var lastLayoutMeasureWidth = -1 private var lastLayoutMeasureHeight = -1 - fun createWindow(): Boolean = if (getToken() == null) { - val activity = if (context is Activity) context else LifecycleUtils.getTopActivity() - activity?.findViewById(android.R.id.content)?.post { createWindowInner() } ?: false - } else { - createWindowInner() + fun createWindow(callback: CreateCallback) { + // 如果在onCreate创建单页面浮窗,会存在获取windowToken为空的情况,需要异步创建 + if (config.showPattern == ShowPattern.CURRENT_ACTIVITY && getToken() == null) { + getActivity()?.findViewById(android.R.id.content)?.run { + post { callback.onCreate(createWindowInner()) } + return + } + callback.onCreate(false) + config.callbacks?.createdResult(false, WARN_ACTIVITY_NULL, null) + config.floatCallbacks?.builder?.createdResult?.invoke(false, WARN_ACTIVITY_NULL, null) + } else callback.onCreate(createWindowInner()) } private fun createWindowInner(): Boolean = try { @@ -92,10 +103,10 @@ internal class FloatingWindowHelper(val context: Context, var config: FloatConfi } } - private fun getToken(): IBinder? { - val activity = if (context is Activity) context else LifecycleUtils.getTopActivity() - return activity?.window?.decorView?.windowToken - } + private fun getActivity() = + if (context is Activity) context else LifecycleUtils.getTopActivity() + + private fun getToken(): IBinder? = getActivity()?.window?.decorView?.windowToken /** * 将自定义的布局,作为xml布局的父布局,添加到windowManager中, @@ -388,18 +399,21 @@ internal class FloatingWindowHelper(val context: Context, var config: FloatConfi } /** - * 更新浮窗坐标 + * 更新浮窗坐标信息 */ - fun updateFloat(x: Int, y: Int) { + fun updateFloat(x: Int = -1, y: Int = -1, width: Int = -1, height: Int = -1) { frameLayout?.let { - if (x == -1 && y == -1) { + if (x == -1 && y == -1 && width == -1 && height == -1) { // 未指定具体坐标,执行吸附动画 it.postDelayed({ touchUtils.updateFloat(it, params, windowManager) }, 200) } else { - params.x = x - params.y = y + if (x != -1) params.x = x + if (y != -1) params.y = y + if (width != -1) params.width = width + if (height != -1) params.height = height windowManager.updateViewLayout(it, params) } } } } + diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/core/FloatingWindowManager.kt b/easyfloat/src/main/java/com/lzf/easyfloat/core/FloatingWindowManager.kt index 4bf7b51..3e13e44 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/core/FloatingWindowManager.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/core/FloatingWindowManager.kt @@ -10,7 +10,7 @@ import java.util.concurrent.ConcurrentHashMap /** * @author: Liuzhenfeng * @date: 12/1/20 23:36 - * @Description: + * @Description: 负责多个悬浮窗的管理 */ internal object FloatingWindowManager { @@ -24,7 +24,11 @@ internal object FloatingWindowManager { fun create(context: Context, config: FloatConfig) { if (!checkTag(config)) { val helper = FloatingWindowHelper(context, config) - if (helper.createWindow()) windowMap[config.floatTag!!] = helper + helper.createWindow(object : FloatingWindowHelper.CreateCallback { + override fun onCreate(success: Boolean) { + if (success) windowMap[config.floatTag!!] = helper + } + }) } else { // 存在相同的tag,直接创建失败 config.callbacks?.createdResult(false, WARN_REPEATED_TAG, null) diff --git a/easyfloat/src/main/java/com/lzf/easyfloat/widget/DefaultCloseView.kt b/easyfloat/src/main/java/com/lzf/easyfloat/widget/DefaultCloseView.kt index 491d622..9a0e620 100644 --- a/easyfloat/src/main/java/com/lzf/easyfloat/widget/DefaultCloseView.kt +++ b/easyfloat/src/main/java/com/lzf/easyfloat/widget/DefaultCloseView.kt @@ -12,7 +12,7 @@ import com.lzf.easyfloat.utils.DisplayUtils * @author: liuzhenfeng * @date: 2020/10/25 11:16 * @Package: com.lzf.easyfloat.widget - * @Description: + * @Description: 自定义拖拽关闭视图,支持椭圆、矩形、半圆 */ class DefaultCloseView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 @@ -43,7 +43,7 @@ class DefaultCloseView @JvmOverloads constructor( context.theme.obtainStyledAttributes(attrs, R.styleable.DefaultCloseView, 0, 0).apply { normalColor = getColor(R.styleable.DefaultCloseView_normalColor, normalColor) inRangeColor = getColor(R.styleable.DefaultCloseView_inRangeColor, inRangeColor) - shapeType = getInt(R.styleable.DefaultCloseView_shapeType, shapeType) + shapeType = getInt(R.styleable.DefaultCloseView_closeShapeType, shapeType) zoomSize = getDimension(R.styleable.DefaultCloseView_zoomSize, zoomSize) }.recycle() diff --git a/easyfloat/src/main/res/layout/default_close_layout.xml b/easyfloat/src/main/res/layout/default_close_layout.xml index 14dd80b..82ae8c8 100644 --- a/easyfloat/src/main/res/layout/default_close_layout.xml +++ b/easyfloat/src/main/res/layout/default_close_layout.xml @@ -1,33 +1,33 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="110dp" + android:paddingHorizontal="50dp" + app:closeShapeType="oval" + app:inRangeColor="#99FF0000" + app:normalColor="#99000000" + app:zoomSize="4dp"> + android:id="@+id/tv_delete" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_centerHorizontal="true" + android:layout_marginBottom="24dp" + android:gravity="center" + android:text="@string/delete_floating_window" + android:textColor="#FFFFFF" + android:textSize="12sp" /> + android:id="@+id/iv_delete" + android:layout_width="20dp" + android:layout_height="20dp" + android:layout_above="@id/tv_delete" + android:layout_centerHorizontal="true" + android:layout_marginBottom="6dp" + android:src="@drawable/icon_delete_normal" /> diff --git a/easyfloat/src/main/res/values/attrs.xml b/easyfloat/src/main/res/values/attrs.xml index 76a4f41..236b26f 100644 --- a/easyfloat/src/main/res/values/attrs.xml +++ b/easyfloat/src/main/res/values/attrs.xml @@ -40,7 +40,7 @@ - + diff --git a/easyfloat/src/test/java/com/lzf/easyfloat/ExampleUnitTest.java b/easyfloat/src/test/java/com/lzf/easyfloat/ExampleUnitTest.java deleted file mode 100644 index 58473e8..0000000 --- a/easyfloat/src/test/java/com/lzf/easyfloat/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.lzf.easyfloat; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/example/build.gradle b/example/build.gradle index cd14bdf..96220b8 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -3,11 +3,11 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion 30 + compileSdkVersion 31 defaultConfig { applicationId "com.lzf.easyfloat.example" minSdkVersion 19 - targetSdkVersion 30 + targetSdkVersion 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -53,5 +53,5 @@ dependencies { implementation project(path: ':easyfloat') implementation 'cn.bingoogolapple:bga-swipebacklayout:2.0.1@aar' implementation "androidx.cardview:cardview:1.0.0" - implementation 'androidx.navigation:navigation-ui-ktx:2.3.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0' } diff --git a/example/release/EasyFloat.apk b/example/release/EasyFloat.apk index a092de4..6d20985 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/activity/BaseActivity.kt b/example/src/main/java/com/lzf/easyfloat/example/activity/BaseActivity.kt index 3b8e902..8617582 100644 --- a/example/src/main/java/com/lzf/easyfloat/example/activity/BaseActivity.kt +++ b/example/src/main/java/com/lzf/easyfloat/example/activity/BaseActivity.kt @@ -1,5 +1,6 @@ package com.lzf.easyfloat.example.activity +import android.annotation.SuppressLint import android.content.Context import android.os.Bundle import android.os.VibrationEffect @@ -55,6 +56,7 @@ open class BaseActivity : AppCompatActivity(), BGASwipeBackHelper.Delegate { bgaSwipeBackHelper.backward() } + @SuppressLint("MissingPermission") fun setVibrator(inRange: Boolean) { if (!vibrator.hasVibrator() || (inRange && vibrating)) return vibrating = inRange diff --git a/example/src/main/java/com/lzf/easyfloat/example/activity/BorderTestActivity.kt b/example/src/main/java/com/lzf/easyfloat/example/activity/BorderTestActivity.kt index b509933..6bc6122 100644 --- a/example/src/main/java/com/lzf/easyfloat/example/activity/BorderTestActivity.kt +++ b/example/src/main/java/com/lzf/easyfloat/example/activity/BorderTestActivity.kt @@ -13,7 +13,7 @@ import kotlinx.android.synthetic.main.activity_border_test.* * @author: liuzhenfeng * @date: 3/9/21 11:27 * @Package: com.lzf.easyfloat.example.activity - * @Description: + * @Description: 悬浮窗边界测试页面 */ class BorderTestActivity : BaseActivity() { diff --git a/example/src/main/java/com/lzf/easyfloat/example/activity/JavaTestActivity.java b/example/src/main/java/com/lzf/easyfloat/example/activity/JavaTestActivity.java index c4de4d7..92dd66a 100644 --- a/example/src/main/java/com/lzf/easyfloat/example/activity/JavaTestActivity.java +++ b/example/src/main/java/com/lzf/easyfloat/example/activity/JavaTestActivity.java @@ -99,39 +99,25 @@ private void test() { // 浮窗的一些状态回调,如:创建结果、显示、隐藏、销毁、touchEvent、拖拽过程、拖拽结束。 .registerCallbacks(new OnFloatCallbacks() { @Override - public void createdResult(boolean isCreated, @Nullable String msg, @Nullable View view) { - - } + public void createdResult(boolean isCreated, @Nullable String msg, @Nullable View view) { } @Override - public void show(@NotNull View view) { - - } + public void show(@NotNull View view) { } @Override - public void hide(@NotNull View view) { - - } + public void hide(@NotNull View view) { } @Override - public void dismiss() { - - } + public void dismiss() { } @Override - public void touchEvent(@NotNull View view, @NotNull MotionEvent event) { - - } + public void touchEvent(@NotNull View view, @NotNull MotionEvent event) { } @Override - public void drag(@NotNull View view, @NotNull MotionEvent event) { - - } + public void drag(@NotNull View view, @NotNull MotionEvent event) { } @Override - public void dragEnd(@NotNull View view) { - - } + public void dragEnd(@NotNull View view) { } }) // Kotlin DSL实现回调效果,和registerCallbacks二选一即可,该方式主要针对Kotlin,Java使用起来并不怎么方便 .registerCallback(builder -> { 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 4b9b693..9185c4e 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 @@ -61,7 +61,7 @@ class MainActivity : BaseActivity(), View.OnClickListener { openBorderTest.setOnClickListener(this) // 测试activity中onCreate就启动浮框 -// showActivity2() +// showActivityFloat(TAG_1) } override fun onClick(v: View?) { @@ -279,9 +279,12 @@ class MainActivity : BaseActivity(), View.OnClickListener { it.findViewById(R.id.ivScale).onScaledListener = object : ScaleImage.OnScaledListener { override fun onScaled(x: Float, y: Float, event: MotionEvent) { - params.width = max(params.width + x.toInt(), 200) - params.height = max(params.height + y.toInt(), 200) - content.layoutParams = params + params.width = max(params.width + x.toInt(), 400) + params.height = max(params.height + y.toInt(), 300) + // 更新xml根布局的大小 +// content.layoutParams = params + // 更新悬浮窗的大小,可以避免在其他应用横屏时,宽度受限 + EasyFloat.updateFloat(tag, width = params.width, height = params.height) } } @@ -293,7 +296,7 @@ class MainActivity : BaseActivity(), View.OnClickListener { } /** - * 检测浮窗权限是否开启,若没有给与申请提示框(非必须,申请依旧是EasyFloat内部内保进行) + * 检测浮窗权限是否开启,若没有给与申请提示框(非必须,申请依旧是EasyFloat内部进行) */ private fun checkPermission(tag: String? = null) { if (PermissionUtils.checkPermission(this)) { diff --git a/example/src/main/java/com/lzf/easyfloat/example/activity/SecondActivity.kt b/example/src/main/java/com/lzf/easyfloat/example/activity/SecondActivity.kt index aa3f917..a08d670 100644 --- a/example/src/main/java/com/lzf/easyfloat/example/activity/SecondActivity.kt +++ b/example/src/main/java/com/lzf/easyfloat/example/activity/SecondActivity.kt @@ -162,34 +162,19 @@ class SecondActivity : BaseActivity() { dragEnd { } } .registerCallbacks(object : OnFloatCallbacks { - override fun createdResult(isCreated: Boolean, msg: String?, view: View?) { + override fun createdResult(isCreated: Boolean, msg: String?, view: View?) {} - } - - override fun show(view: View) { - - } + override fun show(view: View) {} - override fun hide(view: View) { + override fun hide(view: View) {} - } - - override fun dismiss() { - - } + override fun dismiss() {} - override fun touchEvent(view: View, event: MotionEvent) { + override fun touchEvent(view: View, event: MotionEvent) {} - } - - override fun drag(view: View, event: MotionEvent) { - - } - - override fun dragEnd(view: View) { - - } + override fun drag(view: View, event: MotionEvent) {} + override fun dragEnd(view: View) {} }) // 创建浮窗(这是关键哦😂) .show() diff --git a/example/src/main/java/com/lzf/easyfloat/example/widget/MyCustomView.kt b/example/src/main/java/com/lzf/easyfloat/example/widget/MyCustomView.kt index 710845a..4a876ef 100644 --- a/example/src/main/java/com/lzf/easyfloat/example/widget/MyCustomView.kt +++ b/example/src/main/java/com/lzf/easyfloat/example/widget/MyCustomView.kt @@ -10,15 +10,14 @@ import com.lzf.easyfloat.example.R * @author: Liuzhenfeng * @date: 2021/7/14 20:19 * @Package: com.lzf.easyfloat.example.widget - * @Description: + * @Description: 自定义view测试 */ class MyCustomView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr) { init { - (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?) - ?.inflate(R.layout.float_custom, this) + LayoutInflater.from(context).inflate(R.layout.float_custom, this) } } \ No newline at end of file