[Change]
修复V2X弹窗异常 You must call removeView() on the child's parent first Signed-off-by: donghongyu <donghongyu@zhidaoauto.com>
This commit is contained in:
@@ -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 ->
|
||||
|
||||
Reference in New Issue
Block a user