[V2X]弹窗互斥逻辑和更改道路事件展示弹窗的方式

This commit is contained in:
renwj
2022-01-26 16:47:21 +08:00
parent 19ae5c4250
commit 5002b28ef7
73 changed files with 1434 additions and 4681 deletions

View File

@@ -1,11 +1,18 @@
package com.mogo.eagle.core.function.hmi.notification
import android.content.Context
import android.content.ContextWrapper
import android.view.LayoutInflater
import android.view.View
import androidx.appcompat.view.ContextThemeWrapper
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.mogo.eagle.core.function.hmi.notification.enums.SidePattern
import com.mogo.eagle.core.function.hmi.notification.interfaces.OnFloatAnimator
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.reminder.Reminder
import com.mogo.eagle.core.utilcode.reminder.api.impl.ViewReminder
import com.mogo.eagle.core.utilcode.util.WindowUtils
/**
@@ -33,7 +40,6 @@ class WarningFloat {
}
/**
* 浮窗的属性构建类,支持链式调用
*/
@@ -155,6 +161,10 @@ class WarningFloat {
this.config.height = height
}
fun isOverride(isOverride: Boolean) = apply {
this.config.isOverride = isOverride
}
/**
* 创建浮窗包括Activity浮窗和系统浮窗如若系统浮窗无权限先进行权限申请
*/
@@ -164,9 +174,62 @@ class WarningFloat {
config.layoutId == null && config.layoutView == null ->
Logger.e(TAG, "需要传入 layoutId 或 layoutView ")
// 申请浮窗权限
else -> WarningFloatWindowManager.create(activity, config)
else -> {
var content: View? = null
if (config.layoutView != null) {
content = config.layoutView
} else if (config.layoutId != null) {
content = LayoutInflater.from(activity).inflate(config.layoutId!!, null)
}
content?.let {
config.layoutId = null
config.layoutView = it
Reminder.enqueue(getLifecycleOwner(activity), WarningFloatReminder(activity, config, it))
}
}
}
}
private fun getLifecycleOwner(context: Context): LifecycleOwner {
if (context is LifecycleOwner) {
return context
}
if (context is ContextThemeWrapper) {
return getLifecycleOwner(context.baseContext)
}
return ProcessLifecycleOwner.get()
}
internal class WarningFloatReminder(private val activity: Context, private val config: WarningNotificationConfig, content: View): ViewReminder(content) {
private var hasShow = false
override fun show() {
hasShow = !WarningFloatWindowManager.create(activity, config)
}
override fun hide() {
dismiss(config.floatTag, false)
}
override fun isOverride(): Boolean {
return config.isOverride
}
override fun maxProtectDuration(): Long {
return if (hasShow) 0L else super.maxProtectDuration()
}
}
fun isShow(): Boolean = WarningFloatWindowManager.getHelper(config.floatTag)?.isShow() ?: false
fun resetExpireTime(expireTime: Long) {
if (!isShow()) {
return
}
WarningFloatWindowManager.getHelper(config.floatTag)?.resetDownTime(expireTime)
}
}
}

View File

@@ -131,6 +131,11 @@ internal class WarningFloatWindowHelper(
}
}
fun resetDownTime(expireTime: Long) {
config.countDownTime = expireTime
resetDownTime()
}
/**
* 入场动画
*/
@@ -292,5 +297,5 @@ internal class WarningFloatWindowHelper(
windowManager.updateViewLayout(view, params)
}
fun isShow(): Boolean = config.isShow
}

View File

@@ -18,15 +18,17 @@ internal object WarningFloatWindowManager {
* 创建浮窗tag不存在创建tag存在创建失败
* 创建结果通过tag添加到相应的map进行管理
*/
fun create(context: Context, config: WarningNotificationConfig) {
fun create(context: Context, config: WarningNotificationConfig): Boolean {
if (!checkTag(config)) {
val helper = WarningFloatWindowHelper(context, config)
if (helper.createWindow()) windowMap[config.floatTag!!] = helper
return true
} else {
Log.w(TAG, "存在相同的tag延长弹窗时间")
// 存在相同的tag直接创建失败
config.callbacks?.createdResult(false, "存在相同的tag延长弹窗时间", null)
windowMap[config.floatTag!!]?.resetDownTime()
return false
}
}

View File

@@ -65,4 +65,6 @@ data class WarningNotificationConfig(
// 窗口高度
var height: Int = WindowManager.LayoutParams.WRAP_CONTENT
)
) {
var isOverride: Boolean = true
}

View File

@@ -78,12 +78,6 @@ class V2XWarningBroadcastReceiver : BroadcastReceiver() {
if (EventTypeEnum.TYPE_USECASE_ID_IVP.poiType == v2xType.toString()) {
CallerHmiManager.showLimitingVelocity(1)
}
CallerHmiManager.showWarningV2X(
v2xType,
alertContent,
ttsContent,
tag,
null
)
CallerHmiManager.showWarningV2X(v2xType, alertContent, ttsContent, tag, null, true, 5000L)
}
}

View File

@@ -71,7 +71,6 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
// V2X、OBU、云端推送预警弹窗
private var mWarningFloat: WarningFloat.Builder? = null
// 通知、云公告弹窗
private var mNoticeFloat: WarningFloat.Builder? = null
// 超视距、路侧、前车直播
@@ -581,35 +580,30 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
* @param tag tag绑定弹窗的标志
*/
@Synchronized
override fun showWarningV2X(
v2xType: Int,
alertContent: String?,
ttsContent: String?,
tag: String?,
listenerIMoGo: IMoGoWarningStatusListener?
) {
override fun showWarningV2X(v2xType: Int, alertContent: String?, ttsContent: String?, tag: String?, listenerIMoGo: IMoGoWarningStatusListener?, playTts: Boolean, expireTime: Long) {
activity?.let {
val floatWindow = mWarningFloat
val showTag = floatWindow?.config?.floatTag
if (floatWindow == null || TextUtils.isEmpty(showTag)) {
val notificationView = V2XNotificationView(it)
notificationView.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType.toString()))
val warningContent = alertContent ?: EventTypeEnum.getWarningContent(v2xType.toString())
if (warningContent.isEmpty()) {
Logger.e(TAG, "Show warningContent is null or empty!")
return
} else {
notificationView.setWarningContent(warningContent)
}
val notificationView = V2XNotificationView(it)
notificationView.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType.toString()))
val warningContent = alertContent ?: EventTypeEnum.getWarningContent(v2xType.toString())
if (warningContent.isNullOrEmpty()) {
Logger.e(TAG, "Show warningContent is null or empty!")
return
} else {
notificationView.setWarningContent(warningContent)
}
if (mWarningFloat != null && mWarningFloat!!.config.floatTag != tag) {
WarningFloat.dismiss(mWarningFloat!!.config.floatTag, true)
}
if (mWarningFloat != null && mWarningFloat!!.config.floatTag != tag) {
WarningFloat.dismiss(mWarningFloat!!.config.floatTag, true)
}
mWarningFloat = WarningFloat.with(it)
mWarningFloat = WarningFloat.with(it)
.setTag(tag)
.setLayout(notificationView)
.setSidePattern(SidePattern.RESULT_TOP)
.setCountDownTime(5000)
.setCountDownTime(expireTime)
.setGravity(Gravity.CENTER_HORIZONTAL, offsetY = 110)
.setImmersionStatusBar(true)
.addWarningStatusListener(listenerIMoGo)
@@ -617,37 +611,45 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
override fun onShow() {
// 创建弹窗成功才进行TTS播报
Logger.d(
"MoGoWarningFragment",
"mWarningFloat = $mWarningFloat---ttsContent = $ttsContent"
"MoGoWarningFragment",
"mWarningFloat = $mWarningFloat---ttsContent = $ttsContent"
)
if (mWarningFloat != null && !TextUtils.isEmpty(ttsContent)) {
if (mWarningFloat != null && !TextUtils.isEmpty(ttsContent) && playTts) {
Logger.d("MoGoWarningFragment", "---> ttsContent = $ttsContent")
AIAssist.getInstance(activity)
.speakTTSVoice(ttsContent)
.speakTTSVoice(ttsContent)
}
}
})
.setAnimator(object : DefaultAnimator() {
override fun enterAnim(
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
): Animator? =
super.enterAnim(view, params, windowManager, sidePattern)?.apply {
interpolator = OvershootInterpolator()
}
super.enterAnim(view, params, windowManager, sidePattern)?.apply {
interpolator = OvershootInterpolator()
}
override fun exitAnim(
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
): Animator? =
super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200)
super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200)
})
.show()
} else {
if (floatWindow.isShow()) {
val notification = floatWindow.config.layoutView as? V2XNotificationView
if (alertContent?.isNotEmpty() == true) {
notification?.setWarningContent(alertContent)
floatWindow.resetExpireTime(expireTime)
}
}
}
}
}