[6.7.0]UI调整

This commit is contained in:
xuxinchao
2024-09-26 15:54:29 +08:00
parent aaa63597ba
commit 04c1930199
14 changed files with 798 additions and 66 deletions

View File

@@ -610,25 +610,25 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
override fun onAutopilotStatistics(statistics: AutopilotStatistics?) {
statistics?.let {
Log.i(TAG,"onAutopilotStatistics status = "+ it.status)
if(it.status == AutopilotStatistics.AUTOPILOT_START_STATUS.FAILED){
// if(it.status == AutopilotStatistics.AUTOPILOT_START_STATUS.FAILED){
//触发一键上报
ThreadUtils.runOnUiThread{
val activity = AppStateManager.currentActivity()
if (activity !is AppCompatActivity) {
return@runOnUiThread
}
if(reportTypeWindow == null){
reportTypeWindow = ReportTypeWindow(activity)
reportTypeWindow?.setClickListener(object: ReportTypeWindow.ClickListener{
override fun closeWindow() {
reportTypeWindow?.hideFloatWindow()
reportTypeWindow = null
}
})
}
reportTypeWindow?.showOneClickReportWindow(xPosition,yPosition)
}
}
// ThreadUtils.runOnUiThread{
// val activity = AppStateManager.currentActivity()
// if (activity !is AppCompatActivity) {
// return@runOnUiThread
// }
// if(reportTypeWindow == null){
// reportTypeWindow = ReportTypeWindow(activity)
// reportTypeWindow?.setClickListener(object: ReportTypeWindow.ClickListener{
// override fun closeWindow() {
// reportTypeWindow?.hideFloatWindow()
// reportTypeWindow = null
// }
// })
// }
// reportTypeWindow?.showOneClickReportWindow(xPosition,yPosition)
// }
// }
}
}

View File

@@ -417,25 +417,25 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
when (motionEvent?.action) {
MotionEvent.ACTION_DOWN -> {
// 获取相对View的坐标即以此View左上角为原点
mInViewX = motionEvent.x
mInViewY = motionEvent.y
// 获取相对屏幕的坐标,即以屏幕左上角为原点
mInScreenX = motionEvent.rawX
mInScreenY = motionEvent.rawY
}
MotionEvent.ACTION_MOVE -> {
// 更新浮动窗口位置参数
mInScreenX = motionEvent.rawX
mInScreenY = motionEvent.rawY
mWindowParams!!.x = (mInScreenX - mInViewX).toInt()
mWindowParams!!.y = (mInScreenY - mInViewY).toInt()
// 手指移动的时候更新小悬浮窗的位置
mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
}
}
// when (motionEvent?.action) {
// MotionEvent.ACTION_DOWN -> {
// // 获取相对View的坐标即以此View左上角为原点
// mInViewX = motionEvent.x
// mInViewY = motionEvent.y
// // 获取相对屏幕的坐标,即以屏幕左上角为原点
// mInScreenX = motionEvent.rawX
// mInScreenY = motionEvent.rawY
// }
// MotionEvent.ACTION_MOVE -> {
// // 更新浮动窗口位置参数
// mInScreenX = motionEvent.rawX
// mInScreenY = motionEvent.rawY
// mWindowParams!!.x = (mInScreenX - mInViewX).toInt()
// mWindowParams!!.y = (mInScreenY - mInViewY).toInt()
// // 手指移动的时候更新小悬浮窗的位置
// mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
// }
// }
return true
}

View File

@@ -3,7 +3,7 @@
<item>
<shape>
<!-- 边框颜色 -->
<solid android:color="#8996C7"/>
<solid android:color="#A3A3A3"/>
<corners
android:bottomLeftRadius="@dimen/dp_8"
android:bottomRightRadius="@dimen/dp_8"
@@ -20,7 +20,7 @@
android:right="@dimen/dp_1" >
<shape>
<!-- View填充颜色 -->
<solid android:color="#F2161927" />
<solid android:color="#2E323A" />
<corners
android:bottomLeftRadius="@dimen/dp_8"
android:bottomRightRadius="@dimen/dp_8"

View File

@@ -6,5 +6,5 @@
android:angle="270"
/>
<corners
android:radius="@dimen/dp_0"/>
android:radius="@dimen/dp_10"/>
</shape>

View File

@@ -191,6 +191,8 @@
android:visibility="gone"
android:layout_marginTop="@dimen/dp_m_5"
android:paddingTop="@dimen/dp_5"
android:layout_marginStart="@dimen/dp_m_1"
android:layout_marginEnd="@dimen/dp_m_1"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -8,7 +8,9 @@ import com.mogo.eagle.core.data.enums.Carmodel
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxEventListener
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.bone.tab.FaultReasonView
import com.mogo.eagle.core.function.hmi.bone.tab.ReportTypeView
import com.mogo.eagle.core.function.hmi.bone.tab.WorkOrderView
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
@@ -94,8 +96,23 @@ class BoneTabLayout @JvmOverloads constructor(
override fun openWorkOrderView() {
workOrderView.visibility = VISIBLE
}
override fun closeReportView() {
updateTabType(TabType.REPORT_INFO)
}
})
faultReasonView.setClickListener(object: FaultReasonView.ClickListener{
override fun closeFaultReasonView() {
updateTabType(TabType.REPORT_INFO)
}
})
workOrderView.setClickListener(object: WorkOrderView.ClickListener{
override fun closeWorkOrderView() {
updateTabType(TabType.REPORT_INFO)
}
})
}
fun setCarNo(carNo: String?) {

View File

@@ -325,6 +325,7 @@ class FaultReasonView @JvmOverloads constructor(
//取消
tvFaultCancel.setOnClickListener {
this@FaultReasonView.visibility = View.GONE
clickListener?.closeFaultReasonView()
}
}
@@ -430,7 +431,7 @@ class FaultReasonView @JvmOverloads constructor(
}
interface ClickListener {
fun closeWindow()
fun closeFaultReasonView()
}
/**
@@ -448,6 +449,7 @@ class FaultReasonView @JvmOverloads constructor(
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this@FaultReasonView.visibility = View.GONE
clickListener?.closeFaultReasonView()
},1500)
}
}

View File

@@ -120,8 +120,7 @@ class ReportTypeView @JvmOverloads constructor(
//故障类
tvReportTypeFault.setOnClickListener {
//TODO 更改!
if(!ProjectUtils.isSaas()){
if(ProjectUtils.isSaas()){
clickListener?.openFaultReasonView()
}else{
//展示工单上报弹窗
@@ -144,10 +143,12 @@ class ReportTypeView @JvmOverloads constructor(
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this@ReportTypeView.visibility = View.GONE
clickListener?.closeReportView()
},1500)
}else{
ToastUtils.showShort("主动录包命令下发失败")
this@ReportTypeView.visibility = View.GONE
clickListener?.closeReportView()
}
}
}
@@ -172,6 +173,7 @@ class ReportTypeView @JvmOverloads constructor(
if(!hasReportOperate){
ThreadUtils.runOnUiThread {
this@ReportTypeView.visibility = View.GONE
clickListener?.closeReportView()
}
}
}
@@ -201,6 +203,7 @@ class ReportTypeView @JvmOverloads constructor(
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this.visibility = View.GONE
clickListener?.closeReportView()
},1500)
}
}
@@ -210,6 +213,7 @@ class ReportTypeView @JvmOverloads constructor(
ToastUtils.showShort("故障原因上报失败$msg")
ThreadUtils.runOnUiThread {
this.visibility = View.GONE
clickListener?.closeReportView()
}
}
@@ -252,6 +256,8 @@ class ReportTypeView @JvmOverloads constructor(
interface ClickListener {
fun openFaultReasonView()
fun openWorkOrderView()
fun closeReportView()
}
fun setClickListener(clickListener: ClickListener) {

View File

@@ -73,6 +73,8 @@ class WorkOrderView @JvmOverloads constructor(
var ret = 0 // 函数调用返回值
private var audioStatus = false
private var clickListener: ClickListener? = null
init {
LayoutInflater.from(context).inflate(R.layout.view_work_order, this, true)
initView()
@@ -90,7 +92,7 @@ class WorkOrderView @JvmOverloads constructor(
private fun initEvent(){
CallerDevaToolsListenerManager.addListener(TAG, this)
//弹窗展示时间
tv_work_order_time.text = resources.getString(R.string.work_order_time) +
tv_work_order_time.text =
millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())
wrap_radio_group.setOnCheckedChangeListener{_, checkedId ->
@@ -197,6 +199,7 @@ class WorkOrderView @JvmOverloads constructor(
//取消
tv_work_order_cancel.setOnClickListener {
this@WorkOrderView.visibility = View.GONE
clickListener?.closeWorkOrderView()
}
}
@@ -302,6 +305,7 @@ class WorkOrderView @JvmOverloads constructor(
ToastUtils.showShort("工单上报成功")
ThreadUtils.runOnUiThread {
this@WorkOrderView.visibility = View.GONE
clickListener?.closeWorkOrderView()
}
}
@@ -309,4 +313,12 @@ class WorkOrderView @JvmOverloads constructor(
ToastUtils.showShort("工单上报失败")
}
interface ClickListener{
fun closeWorkOrderView()
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
}

View File

@@ -0,0 +1,206 @@
package com.mogo.eagle.core.function.hmi.ui.msgbox
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.deva.report.ReportEntity
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.msgbox.FMInfoMsg
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxCountDownBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.MsgCategory
import com.mogo.eagle.core.data.msgbox.MsgFmData
import com.mogo.eagle.core.function.api.autopilot.IMoGoNodeStateListener
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxListener
import com.mogo.eagle.core.function.api.order.IOrderListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerNodeStateListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxListenerManager
import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.msgbox.adapter.MsgBoxBubbleAdapter
import com.mogo.eagle.core.function.msgbox.MsgBoxConfig
import com.mogo.eagle.core.utilcode.util.SoundPoolUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhjt.mogo.adas.data.bean.NodeStateInfo
import kotlinx.android.synthetic.main.layout_driver_msg_box_bubble.view.clMsgBubbleLayout
import kotlinx.android.synthetic.main.layout_msg_box_bubble.view.llMsgBubbleLayout
import kotlinx.android.synthetic.main.layout_msg_box_bubble.view.rvBubbleList
/**
* 司机端消息盒子气泡视图改版视图
*/
class MsgBoxBubbleView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMsgBoxListener, IOrderListener{
init {
LayoutInflater.from(context).inflate(R.layout.layout_msg_box_bubble, this, true)
initView()
}
var msgBoxBubbleAdapter: MsgBoxBubbleAdapter ?= null
private val TAG = "DriverMsgBoxBubbleView"
private val dataList :ArrayList<MsgBoxCountDownBean> = ArrayList()
private var isShowData = true
private var isShowSummary = false //是否展示汇总消息
private fun initView(){
val linearLayoutManager = LinearLayoutManager(context)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
linearLayoutManager.stackFromEnd = true
linearLayoutManager.reverseLayout = true
msgBoxBubbleAdapter = MsgBoxBubbleAdapter(context as Activity)
msgBoxBubbleAdapter?.setChangeListener(object : MsgBoxBubbleAdapter.ChangeViewListener{
override fun notifyView() {
if(dataList.isEmpty()){
llMsgBubbleLayout.visibility = View.GONE
}
}
})
rvBubbleList.adapter = msgBoxBubbleAdapter
rvBubbleList.layoutManager = linearLayoutManager
}
/**
* 是否展示接收消息,消息盒子打开状态下不再展示气泡消息
* @param show true 展示false 不展示
*/
fun isShowData(show: Boolean){
isShowData = show
}
override fun onDataChanged(category: MsgCategory, msgBoxBean: MsgBoxBean) {
UiThreadHandler.post({
when (category) {
MsgCategory.NOTICE -> {
MsgBoxConfig.noticeList.add(msgBoxBean)
}
MsgCategory.SYS_INFO -> {
MsgBoxConfig.systemInfoList.add(msgBoxBean)
}
MsgCategory.RECORD_BAG -> {
MsgBoxConfig.recordBagList.add(msgBoxBean)
}
else -> {}
}
if(isShowData){
if(category == MsgCategory.RECORD_BAG){
if(!FunctionBuildConfig.isDemoMode && FunctionBuildConfig.isShowBagRecordWindow){
//弹出被动录包弹窗
CallerDevaToolsManager.onReceiveBadCaseRecord(msgBoxBean,context as Activity,true)
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
}
} else if(category == MsgCategory.SYS_INFO){
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
if(msgBoxBean.type == MsgBoxType.REPORT){
val reportMsg = msgBoxBean.bean as ReportEntity
//P8-P1均只收在消息盒子里P0消息盒子弹出其中P0弹出时需要判断驾驶状态非自动驾驶、非平行驾驶状态不弹出其余状态弹出
var isShowReport = false
for(action in reportMsg.actionsList){
if("ACTION_MANUAL_HANDLE_IMMEDIATELY" == action){
if(CallerAutoPilotStatusListenerManager.getState() == 2
|| CallerAutoPilotStatusListenerManager.getState() == 7){
isShowReport = true
}
}
}
if(isShowReport){
//展示消息
showData(msgBoxBean)
}
}
} else if(category == MsgCategory.FM_INFO){
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
if(FunctionBuildConfig.isTakeoverRemind){
//属于停车警示(包括择机靠边停车、立即舒适停车、就地紧急停车)时,需要弹出消息气泡并伴有提示音
val fmInfoMsg = msgBoxBean.bean as FMInfoMsg
var curFaultLevel = 5 //默认级别遍历数组找出级别最高的level数越小级别越高
fmInfoMsg.fmInfoList?.forEach { faultInfo ->
if(faultInfo.faultActionCount>0){
faultInfo.faultActionList.forEach {actionCode ->
//获取建议操作级别,得到建议操作级别最高的操作
if(MsgFmData.FaultAction.getFaultLevel(actionCode) < curFaultLevel){
curFaultLevel = MsgFmData.FaultAction.getFaultLevel(actionCode)
}
}
}
}
//P0级消息弹出时需要判断驾驶状态非自动驾驶、非平行驾驶状态不弹出其余状态弹出
if(curFaultLevel == 0){
//自动驾驶状态 0是不可用 1是ready 2是自动驾驶中 7:平行驾驶中
if(CallerAutoPilotStatusListenerManager.getState() == 2
|| CallerAutoPilotStatusListenerManager.getState() == 7){
// 6.6.0 ,因为 FSM 模块也会弹修改为只有没有 FSM 模块才弹
// 6.6.0 20240823 考虑到 FSM 初期消息不一定全,先不加限制,产品先观察功能后再考虑是否过滤
// if (hasNoneFSMNode()) {
//语音提示
try {
SoundPoolUtils.getSoundPool().playSoundWithRedId(context,R.raw.weak_net_tips)
}catch (e: Exception){
e.printStackTrace()
}
//展示消息
showData(msgBoxBean)
//}
}
}
}
} else{
if(msgBoxBean.sourceType == DataSourceType.SUMMARY){
//在一次订单中汇总消息只展示一次
if(isShowSummary){
showData(msgBoxBean)
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
isShowSummary = false
}
}else{
if(msgBoxBean.type == MsgBoxType.V2X){
//鹰眼650需求不再展示气泡态V2X消息
return@post
}
showData(msgBoxBean)
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
}
}
}
}, UiThreadHandler.MODE.QUEUE)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerMsgBoxListenerManager.addListener(TAG,this)
CallerOrderListenerManager.addListener(TAG,this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerMsgBoxListenerManager.removeListener(TAG)
CallerOrderListenerManager.removeListener(TAG)
}
override fun onUpdateOrderStatus(inOrder: Boolean) {
isShowSummary = inOrder
}
private fun showData(msgBoxBean: MsgBoxBean){
clMsgBubbleLayout.visibility = View.VISIBLE
val msgBoxCountDownBean = MsgBoxCountDownBean(msgBoxBean)
dataList.add(msgBoxCountDownBean)
msgBoxBubbleAdapter?.setData(dataList)
}
}

View File

@@ -0,0 +1,484 @@
package com.mogo.eagle.core.function.hmi.ui.msgbox.adapter
import android.app.Activity
import android.os.CountDownTimer
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.deva.report.ReportEntity
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.AutopilotMsg
import com.mogo.eagle.core.data.msgbox.FMInfoMsg
import com.mogo.eagle.core.data.msgbox.FSMMsg
import com.mogo.eagle.core.data.msgbox.MsgBoxCountDownBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.MsgFmData
import com.mogo.eagle.core.data.msgbox.NoticeFrCloudMsg
import com.mogo.eagle.core.data.msgbox.OperationMsg
import com.mogo.eagle.core.data.msgbox.SSMMsg
import com.mogo.eagle.core.data.msgbox.V2XMsg
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp
import com.mogo.eagle.core.utilcode.mogo.glide.transform.GlideRoundedCornersTransform
import com.mogo.eagle.core.utilcode.util.ResourceUtils.getDrawable
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.getHourMinFormat
import com.mogo.eagle.core.widget.RoundCanClickConstraintLayout
class MsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var data: ArrayList<MsgBoxCountDownBean> ?= null
private var changeViewListener: ChangeViewListener?=null
private val operation: Int = 1
private val operationReturn: Int = 10
private val operationStop: Int = 11
private val operationDoorSwitchFail: Int = 13 //车门开启、关闭失败
private val notice: Int = 2
private val v2x: Int = 3
private val report: Int = 4
private val summary: Int = 5
private val fm: Int = 6
private val ssm: Int = 7
private val autopilot: Int = 8
private val fsm: Int = 9
private val none: Int = 10
fun setData(data: ArrayList<MsgBoxCountDownBean>){
this.data = data
if(data.size>4){
data.removeAt(0)
}
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
operation -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_operation,parent,false)
return BubbleOperationHolder(view)
}
operationReturn -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_bubble_operation_return, parent, false)
return BubbleOperationReturnHolder(view)
}
operationStop -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_bubble_operation_stop, parent, false)
return BubbleOperationStopHolder(view)
}
operationDoorSwitchFail ->{
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_bubble_operation_door, parent, false)
return BubbleOperationDoorFailHolder(view)
}
report -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_report,parent,false)
return BubbleReportHolder(view)
}
notice -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_notice,parent,false)
return BubbleNoticeHolder(view)
}
summary -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_summary,parent,false)
return BubbleSummaryHolder(view)
}
fm -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_fm,parent,false)
return BubbleFmHolder(view)
}
ssm -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_ssm,parent,false)
return BubbleSsmHolder(view)
}
autopilot -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_autopilot,parent,false)
return BubbleAutopilotHolder(view)
}
fsm -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_fsm,parent,false)
return BubbleFSMHolder(view)
}
else -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_v2x,parent,false)
return BubbleV2XHolder(view)
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is BubbleOperationHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean
val operationMsg = msgBoxBean.bean as OperationMsg
holder.tvBubbleOperationTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvBubbleOperationContent.text = operationMsg.content
holder.clBubbleOperationLayout.setOnClickListener {
CallerMsgBoxEventListenerManager.invokeBubbleOperationListener(msgBoxBean)
}
}
}
//运营平台还车通知
is BubbleOperationReturnHolder -> {
data?.let {
val operationReturnMsg = it[position].msgBoxBean.bean as OperationMsg
holder.tvOperationReturnContent.text = operationReturnMsg.content
holder.tvOperationReturnTime.text =
TimeUtils.millis2String(operationReturnMsg.timestamp, getHourMinFormat())
}
}
//运营平台靠边停车
is BubbleOperationStopHolder -> {
data?.let {
val operationStopMsg = it[position].msgBoxBean.bean as OperationMsg
holder.tvOperationStopTime.text =
TimeUtils.millis2String(operationStopMsg.timestamp, getHourMinFormat())
holder.tvOperationStopContent.text = operationStopMsg.content
}
}
//车门开启关闭失败
is BubbleOperationDoorFailHolder -> {
data?.let{
val operationDoorMsg = it[position].msgBoxBean.bean as OperationMsg
holder.tvOperationDoorTime.text =
TimeUtils.millis2String(operationDoorMsg.timestamp, getHourMinFormat())
holder.tvOperationDoorContent.text = operationDoorMsg.content
}
}
//系统信息消息
is BubbleReportHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean
val reportEntity = msgBoxBean.bean as ReportEntity
holder.tvBubbleReportTime.text = "时间:${TimeUtils.millis2String(it[position].msgBoxBean.timestamp)}"
holder.tvBubbleReceiveTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
var resultStr = "类型:"
for (result in reportEntity.resultList){
resultStr = "${resultStr}${CallerAutoPilotControlManager.getReportResultDesc(result)}"
}
holder.tvBubbleReportType.text = resultStr
holder.clReportLayout.setOnClickListener {
CallerMsgBoxEventListenerManager.invokeBubbleReportListener(msgBoxBean)
}
}
}
//云公告消息
is BubbleNoticeHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean.bean
val noticeFrCloudMsg = msgBoxBean as NoticeFrCloudMsg
if(noticeFrCloudMsg.type == 0){
val noticeNormalData = noticeFrCloudMsg.noticeNormalData
holder.tvNoticeTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvNoticeContent.text = noticeNormalData?.content
GlideApp.with(activity).load(noticeNormalData?.imageUrl).optionalTransform(
GlideRoundedCornersTransform(
20f,
GlideRoundedCornersTransform.CornerType.ALL
)
).into(holder.ivNoticeImage)
holder.tvNoticeCheck.setOnClickListener {
//云公告
if (noticeNormalData != null) {
CallerHmiManager.showNoticeNormalData(noticeNormalData)
}
}
}else if(noticeFrCloudMsg.type == 1){
val noticeTrafficStylePushData = noticeFrCloudMsg.trafficPushData
holder.tvNoticeTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvNoticeContent.text = noticeTrafficStylePushData?.content
GlideApp.with(activity).load(noticeTrafficStylePushData?.poiImgUrl).optionalTransform(
GlideRoundedCornersTransform(
20f,
GlideRoundedCornersTransform.CornerType.ALL
)
).into(holder.ivNoticeImage)
holder.tvNoticeCheck.setOnClickListener {
//云公告
if (noticeTrafficStylePushData != null) {
CallerHmiManager.showTrafficBanner(noticeTrafficStylePushData)
}
}
}
}
}
//V2X消息
is BubbleV2XHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean
val v2XMsg = msgBoxBean.bean as V2XMsg
holder.tvV2XTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvV2XContent.text = v2XMsg.content
holder.ivV2XImage.setImageDrawable(ResourcesCompat.getDrawable(activity.resources,EventTypeEnumNew.getUpdateIconRes(v2XMsg.type),null))
holder.clV2XLayout.setOnClickListener {
CallerMsgBoxEventListenerManager.invokeBubbleV2XListener(msgBoxBean)
}
if(v2XMsg.type== EventTypeEnumNew.TYPE_VERIFICATION_SUCCESSFUL.poiType||v2XMsg.type == EventTypeEnumNew.TYPE_DEVICE_STATUS_NORMAL.poiType){
holder.itemView.setBackgroundResource(R.drawable.bg_temp_v2x_success)
}else{
holder.itemView.setBackgroundResource(R.drawable.bg_msg_box_v2x)
}
if(v2XMsg.communicationType.isNullOrEmpty()){
holder.tvV2XTitle.text = EventTypeEnumNew.getEventTitle(v2XMsg.type)
}else{
holder.tvV2XTitle.text = String.format(activity.resources.getString(R.string.v2x_title_content),
v2XMsg.communicationType, EventTypeEnumNew.getEventTitle(v2XMsg.type))
}
}
}
//汇总消息
is BubbleSummaryHolder -> {
data?.let {
val summaryMsg = it[position].msgBoxBean.bean as V2XMsg
holder.tvSummaryTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvSummaryContent.text = summaryMsg.content
}
}
//FM信息
is BubbleFmHolder ->{
data?.let {
val fmMsg = it[position].msgBoxBean.bean as FMInfoMsg
if(fmMsg.policyTime == null){
holder.tvBubbleFmTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
}else{
holder.tvBubbleFmTime.text = TimeUtils.millis2String(fmMsg.policyTime!!,getHourMinFormat())
}
if(fmMsg.fmInfoList?.size == 0){
holder.tvBubbleFmFaultAction.text = "建议操作:暂无"
holder.tvBubbleFmFault.text = MsgFmData.getFmPolicyName(fmMsg.policyCode)
}else{
var curFaultLevel = 5 //默认级别遍历数组找出级别最高的level数越小级别越高
fmMsg.fmInfoList?.forEach { faultInfo ->
if(faultInfo.faultActionCount>0){
faultInfo.faultActionList.forEach {actionCode ->
//获取建议操作级别,得到建议操作级别最高的操作
if(MsgFmData.FaultAction.getFaultLevel(actionCode) < curFaultLevel){
curFaultLevel = MsgFmData.FaultAction.getFaultLevel(actionCode)
}
}
}
}
val faultAction = MsgFmData.FaultAction.getFaultAction(curFaultLevel)
holder.tvBubbleFmFault.text = faultAction
//当出现多个建议操作时,按照整车下电重启、请求人工驾驶接管、请求平行驾驶接管、系统重启、联系硬件工程师、
// 联系运维工程师、联系软件工程师优先级递减的顺序,只展示最高优先级的内容
if(curFaultLevel == 5){
holder.tvBubbleFmFaultAction.text = "建议操作:暂无"
}else{
holder.tvBubbleFmFaultAction.text = "${faultAction}(${MsgFmData.FaultAction.getFaultActionCode(curFaultLevel)})"
}
//不同级别的Icon显示
when(curFaultLevel){
0->{
//重度预警样式
holder.ivBubbleFmImage.setImageDrawable(getDrawable(R.drawable.icon_fm_stop_normal))
}
1,2,3->{
//中度预警样式
holder.ivBubbleFmImage.setImageDrawable(getDrawable(R.drawable.icon_fm_reduce_normal))
}
4,5->{
//轻度预警样式
holder.ivBubbleFmImage.setImageDrawable(getDrawable(R.drawable.icon_fm_warning_normal))
}
}
}
}
}
//SSM连接消息
is BubbleSsmHolder ->{
data?.let {
val ssmMsg = it[position].msgBoxBean.bean as SSMMsg
holder.tvSsmTitle.text = ssmMsg.title
holder.tvSsmContent.text= ssmMsg.content
holder.tvSsmTime.text = TimeUtils.millis2String(ssmMsg.timestamp,getHourMinFormat())
}
}
//域控制器连接消息
is BubbleAutopilotHolder ->{
data?.let {
val autopilotMsg = it[position].msgBoxBean.bean as AutopilotMsg
holder.tvAutopilotTitle.text = autopilotMsg.title
holder.tvAutopilotContent.text = autopilotMsg.content
holder.tvAutopilotTime.text = TimeUtils.millis2String(autopilotMsg.timestamp,getHourMinFormat())
}
}
//FSM消息
is BubbleFSMHolder ->{
data?.let {
val fsmMsg = it[position].msgBoxBean.bean as FSMMsg
holder.tvFSMTitle.text = fsmMsg.title
holder.tvFSMContent.text = fsmMsg.content
holder.tvFSMTime.text = TimeUtils.millis2String(fsmMsg.timestamp,getHourMinFormat())
}
}
}
val msgBoxBean: MsgBoxCountDownBean = data!![position]
msgBoxBean.countDownTimer =object: CountDownTimer(CallerMsgBoxManager.getDismissTime(),1000){
override fun onTick(p0: Long) {
}
override fun onFinish() {
data?.remove(msgBoxBean)
changeViewListener?.notifyView()
notifyDataSetChanged()
}
}
msgBoxBean.countDownTimer?.start()
}
override fun getItemCount() = data?.size ?: 0
override fun getItemViewType(position: Int): Int {
return if(data!![position].msgBoxBean.type == MsgBoxType.OPERATION){
when ((data!![position].msgBoxBean.bean as OperationMsg).type) {
0 -> {
//运营平台还车通知
operationReturn
}
1 -> {
//运营平台靠边停车
operationStop
}
3 -> {
//车门开启关闭失败
operationDoorSwitchFail
}
else -> {
//普通运营平台
operation
}
}
}else if(data!![position].msgBoxBean.type == MsgBoxType.REPORT){
report
}else if(data!![position].msgBoxBean.type == MsgBoxType.NOTICE){
notice
}else if(data!![position].msgBoxBean.type == MsgBoxType.V2X && data!![position].msgBoxBean.sourceType == DataSourceType.SUMMARY){
summary
}else if(data!![position].msgBoxBean.type == MsgBoxType.FMINFO){
fm
}else if(data!![position].msgBoxBean.type == MsgBoxType.SSMINFO){
ssm
}else if(data!![position].msgBoxBean.type == MsgBoxType.AUTOPILOT){
autopilot
}else if(data!![position].msgBoxBean.type == MsgBoxType.FSM){
fsm
} else {
v2x
}
}
fun setChangeListener(listener: ChangeViewListener){
changeViewListener = listener
}
interface ChangeViewListener{
fun notifyView()
}
//车辆系统信息
class BubbleReportHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvBubbleReportTime: TextView = itemView.findViewById(R.id.tvBubbleReportTime)
var tvBubbleReportType: TextView = itemView.findViewById(R.id.tvBubbleReportType)
var tvBubbleReceiveTime: TextView = itemView.findViewById(R.id.tvBubbleReceiveTime)
var clReportLayout: RoundCanClickConstraintLayout = itemView.findViewById(R.id.clReportLayout)
}
//运营平台
class BubbleOperationHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvBubbleOperationTime: TextView = itemView.findViewById(R.id.tvBubbleOperationTime)
var tvBubbleOperationContent: TextView = itemView.findViewById(R.id.tvBubbleOperationContent)
var clBubbleOperationLayout: RoundCanClickConstraintLayout = itemView.findViewById(R.id.clBubbleOperationLayout)
}
//运营平台还车通知
class BubbleOperationReturnHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvOperationReturnTime: TextView = itemView.findViewById(R.id.tvOperationReturnTime)
var tvOperationReturnContent: TextView = itemView.findViewById(R.id.tvOperationReturnContent)
}
//运营平台靠边停车通知
class BubbleOperationStopHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvOperationStopTime: TextView = itemView.findViewById(R.id.tvOperationStopTime)
var tvOperationStopContent: TextView = itemView.findViewById(R.id.tvOperationStopContent)
}
//车门开启关闭失败
class BubbleOperationDoorFailHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvOperationDoorTime: TextView = itemView.findViewById(R.id.tvOperationDoorTime)
var tvOperationDoorContent: TextView = itemView.findViewById(R.id.tvOperationDoorContent)
}
//Notice
class BubbleNoticeHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivNoticeImage: ImageView = itemView.findViewById(R.id.ivNoticeImage)
// var tvNoticeTitle: TextView = itemView.findViewById(R.id.tvNoticeTitle)
var tvNoticeTime: TextView = itemView.findViewById(R.id.tvNoticeTime)
var tvNoticeCheck: TextView = itemView.findViewById(R.id.tvNoticeCheck)
var tvNoticeContent: TextView = itemView.findViewById(R.id.tvNoticeContent)
}
//V2X
class BubbleV2XHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivV2XImage: ImageView = itemView.findViewById(R.id.ivV2XImage)
var tvV2XTime: TextView = itemView.findViewById(R.id.tvV2XTime)
var tvV2XContent: TextView = itemView.findViewById(R.id.tvV2XContent)
var clV2XLayout: ConstraintLayout = itemView.findViewById(R.id.clV2XLayout)
var tvV2XTitle: TextView = itemView.findViewById(R.id.tvV2XTitle)
}
//汇总消息
class BubbleSummaryHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvSummaryContent: TextView = itemView.findViewById(R.id.tvSummaryContent)
var tvSummaryTime: TextView = itemView.findViewById(R.id.tvSummaryTime)
}
//FM消息
class BubbleFmHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvBubbleFmFault: TextView = itemView.findViewById(R.id.tvBubbleFmFault)
var tvBubbleFmFaultAction: TextView = itemView.findViewById(R.id.tvBubbleFmFaultAction)
var tvBubbleFmTime: TextView = itemView.findViewById(R.id.tvBubbleFmTime)
var ivBubbleFmImage: ImageView = itemView.findViewById(R.id.ivBubbleFmImage)
}
//SSM连接消息
class BubbleSsmHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivSsmImage: ImageView = itemView.findViewById(R.id.ivSsmImage)
var tvSsmTitle: TextView = itemView.findViewById(R.id.tvSsmTitle)
var tvSsmTime: TextView = itemView.findViewById(R.id.tvSsmTime)
var tvSsmContent: TextView = itemView.findViewById(R.id.tvSsmContent)
}
//域控制器连接状态消息
class BubbleAutopilotHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivAutopilotImage: ImageView = itemView.findViewById(R.id.ivAutopilotImage)
var tvAutopilotTitle: TextView = itemView.findViewById(R.id.tvAutopilotTitle)
var tvAutopilotTime: TextView = itemView.findViewById(R.id.tvAutopilotTime)
var tvAutopilotContent: TextView = itemView.findViewById(R.id.tvAutopilotContent)
}
//FSM状态消息(现阶段提示启动自驾失败消息过渡阶段提示未来展示fsm消息提醒)
class BubbleFSMHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivFSMImage: ImageView = itemView.findViewById(R.id.ivFSMImage)
var tvFSMTitle: TextView = itemView.findViewById(R.id.tvFSMTitle)
var tvFSMTime: TextView = itemView.findViewById(R.id.tvFSMTime)
var tvFSMContent: TextView = itemView.findViewById(R.id.tvFSMContent)
}
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/llMsgBubbleLayout"
>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvBubbleList"
android:layout_width="@dimen/dp_654"
android:layout_height="wrap_content"
/>
</LinearLayout>

View File

@@ -41,8 +41,8 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="@dimen/dp_280"
android:layout_marginBottom="@dimen/dp_180"
android:layout_marginStart="@dimen/dp_270"
android:layout_marginBottom="@dimen/dp_170"
/>
<com.mogo.eagle.core.function.hmi.bone.tab.FaultReasonView

View File

@@ -23,7 +23,7 @@
android:layout_height="wrap_content"
android:text="@string/fault_reason"
android:textSize="@dimen/sp_40"
android:textColor="@color/white"
android:textColor="#CCFFFFFF"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/view_title_bg"
app:layout_constraintBottom_toBottomOf="@id/view_title_bg"
@@ -41,7 +41,7 @@
app:layout_constraintTop_toTopOf="@id/view_title_bg"
app:layout_constraintBottom_toBottomOf="@id/view_title_bg"
app:layout_constraintEnd_toEndOf="@id/view_title_bg"
android:layout_marginEnd="@dimen/dp_30"
android:layout_marginEnd="@dimen/dp_53"
/>
<View
@@ -60,7 +60,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/work_order_type"
android:textSize="@dimen/sp_32"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/view_type_label"
@@ -74,9 +74,9 @@
android:layout_width="@dimen/dp_779"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/view_type_label"
app:layout_constraintTop_toBottomOf="@id/tv_type_title"
app:layout_constraintLeft_toLeftOf="@id/view_type_label"
android:layout_marginTop="@dimen/dp_18"
android:layout_marginTop="@dimen/dp_15"
>
<RadioButton
@@ -144,7 +144,7 @@
app:layout_constraintTop_toBottomOf="@id/wrap_radio_group"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_40"
/>
<TextView
@@ -215,7 +215,7 @@
app:layout_constraintTop_toBottomOf="@id/iv_time_reduce"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_40"
/>
<TextView
@@ -232,17 +232,6 @@
android:layout_marginStart="@dimen/dp_13"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tv_describe_title"
app:layout_constraintBottom_toBottomOf="@id/tv_describe_title"
app:layout_constraintLeft_toRightOf="@id/tv_describe_title"
android:textSize="@dimen/sp_32"
android:textColor="#CCCCCC"
android:text="@string/fault_note_supplement"
/>
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_describe_input"
android:layout_width="@dimen/dp_779"
@@ -287,7 +276,7 @@
android:textSize="@dimen/sp_36"
android:textStyle="bold"
android:gravity="center"
android:layout_marginTop="@dimen/dp_97"
android:layout_marginTop="@dimen/dp_90"
/>
<TextView
@@ -302,7 +291,7 @@
android:textStyle="bold"
android:gravity="center"
android:background="@drawable/bg_fault_cancel"
android:layout_marginTop="@dimen/dp_97"
android:layout_marginTop="@dimen/dp_90"
/>