From 4a9b9b40664866cca63789bbcf8a41ddcd9a3f86 Mon Sep 17 00:00:00 2001 From: donghongyu Date: Wed, 16 Mar 2022 17:30:06 +0800 Subject: [PATCH] =?UTF-8?q?[Change]=20=E4=BF=AE=E5=A4=8DV2X=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E5=BC=82=E5=B8=B8=20You=20must=20call=20removeView()?= =?UTF-8?q?=20on=20the=20child's=20parent=20first?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: donghongyu --- .../notification/WarningFloatWindowHelper.kt | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/notification/WarningFloatWindowHelper.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/notification/WarningFloatWindowHelper.kt index 52dc5887b2..2060d4c113 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/notification/WarningFloatWindowHelper.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/notification/WarningFloatWindowHelper.kt @@ -24,8 +24,8 @@ import com.mogo.eagle.core.utilcode.util.WindowUtils * 弹窗Window 管理 */ internal class WarningFloatWindowHelper( - val context: Context, - var config: WarningNotificationConfig + val context: Context, + var config: WarningNotificationConfig ) { var TAG = "WarningFloatWindowHelper" @@ -85,7 +85,7 @@ internal class WarningFloatWindowHelper( frameLayout?.tag = config.floatTag // 将浮窗布局文件添加到父容器frameLayout中,并返回该浮窗文件 val floatingView = config.layoutView?.also { frameLayout?.addView(it) } - ?: LayoutInflater.from(context).inflate(config.layoutId!!, frameLayout, true) + ?: LayoutInflater.from(context).inflate(config.layoutId!!, frameLayout, true) // 为了避免创建的时候闪一下,我们先隐藏视图,不能直接设置GONE,否则定位会出现问题 floatingView.visibility = View.INVISIBLE // 将frameLayout添加到系统windowManager中 @@ -142,34 +142,34 @@ internal class WarningFloatWindowHelper( config.statusListenerMapIMoGo.forEach { listener -> listener.onShow() } - if (frameLayout == null|| frameLayout?.isAttachedToWindow == false || config.isAnim) return + if (frameLayout == null || frameLayout?.isAttachedToWindow == false || config.isAnim) return enterAnimator = AnimatorManager(frameLayout!!, params, windowManager, config) - .enterAnim()?.apply { - // 可以延伸到屏幕外,动画结束按需去除该属性,不然旋转屏幕可能置于屏幕外部 - params.flags = - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + .enterAnim()?.apply { + // 可以延伸到屏幕外,动画结束按需去除该属性,不然旋转屏幕可能置于屏幕外部 + params.flags = + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - addListener(object : Animator.AnimatorListener { - override fun onAnimationRepeat(animation: Animator?) {} + addListener(object : Animator.AnimatorListener { + override fun onAnimationRepeat(animation: Animator?) {} - override fun onAnimationEnd(animation: Animator?) { - config.isAnim = false - if (!config.immersionStatusBar) { - // 不需要延伸到屏幕外了,防止屏幕旋转的时候,浮窗处于屏幕外 - params.flags = - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + override fun onAnimationEnd(animation: Animator?) { + config.isAnim = false + if (!config.immersionStatusBar) { + // 不需要延伸到屏幕外了,防止屏幕旋转的时候,浮窗处于屏幕外 + params.flags = + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + } } - } - override fun onAnimationCancel(animation: Animator?) {} + override fun onAnimationCancel(animation: Animator?) {} - override fun onAnimationStart(animation: Animator?) { - floatingView.visibility = View.VISIBLE - config.isAnim = true - } - }) - start() - } + override fun onAnimationStart(animation: Animator?) { + floatingView.visibility = View.VISIBLE + config.isAnim = true + } + }) + start() + } if (enterAnimator == null) { floatingView.visibility = View.VISIBLE windowManager.updateViewLayout(floatingView, params) @@ -183,16 +183,16 @@ internal class WarningFloatWindowHelper( config.statusListenerMapIMoGo.forEach { listener -> listener.onDismiss() } - if (frameLayout == null|| frameLayout?.isAttachedToWindow == false || (config.isAnim && enterAnimator == null)) return + if (frameLayout == null || frameLayout?.isAttachedToWindow == false || (config.isAnim && enterAnimator == null)) return enterAnimator?.cancel() val animator: Animator? = - AnimatorManager(frameLayout!!, params, windowManager, config).exitAnim() + AnimatorManager(frameLayout!!, params, windowManager, config).exitAnim() if (animator == null) remove() else { // 二次判断,防止重复调用引发异常 if (config.isAnim) return config.isAnim = true params.flags = - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS animator.addListener(object : Animator.AnimatorListener { override fun onAnimationRepeat(animation: Animator?) {} @@ -214,7 +214,14 @@ internal class WarningFloatWindowHelper( config.isAnim = false WarningFloatWindowManager.remove(config.floatTag) // removeView是异步删除,在Activity销毁的时候会导致窗口泄漏,所以使用removeViewImmediate直接删除view - windowManager.run { if (force) removeViewImmediate(frameLayout) else removeView(frameLayout) } + windowManager.run { + frameLayout?.removeAllViews() + if (force) { + removeViewImmediate(frameLayout) + } else { + removeView(frameLayout) + } + } } catch (e: Exception) { CallerLogger.e("$M_HMI$TAG", "浮窗关闭出现异常:$e") } @@ -235,9 +242,9 @@ internal class WarningFloatWindowHelper( view.getLocationOnScreen(location) // 通过绝对高度和相对高度比较,判断包含顶部状态栏 val statusBarHeight = - if (location[1] > params.y) WindowUtils.getStatusBarHeight(view.context.applicationContext) else 0 + if (location[1] > params.y) WindowUtils.getStatusBarHeight(view.context.applicationContext) else 0 val parentBottom = - WindowUtils.getScreenHeight(view.context.applicationContext) - statusBarHeight + WindowUtils.getScreenHeight(view.context.applicationContext) - statusBarHeight when (config.gravity) { // 右上 Gravity.END, Gravity.END or Gravity.TOP, Gravity.RIGHT, Gravity.RIGHT or Gravity.TOP ->