From 04c19301992309b154a6ed762cba0e2675ddfb91 Mon Sep 17 00:00:00 2001 From: xuxinchao Date: Thu, 26 Sep 2024 15:54:29 +0800 Subject: [PATCH] =?UTF-8?q?[6.7.0]UI=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../badcase/BadCaseManager.kt | 36 +- .../workorder/TakeOverReasonWindow.kt | 38 +- .../src/main/res/drawable/bg_reason_list.xml | 4 +- .../res/drawable/type_radio_button_select.xml | 2 +- .../main/res/layout/view_take_over_reason.xml | 2 + .../core/function/hmi/bone/BoneTabLayout.kt | 17 + .../function/hmi/bone/tab/FaultReasonView.kt | 4 +- .../function/hmi/bone/tab/ReportTypeView.kt | 10 +- .../function/hmi/bone/tab/WorkOrderView.kt | 14 +- .../hmi/ui/msgbox/MsgBoxBubbleView.kt | 206 ++++++++ .../ui/msgbox/adapter/MsgBoxBubbleAdapter.kt | 484 ++++++++++++++++++ .../main/res/layout/layout_msg_box_bubble.xml | 14 + .../src/main/res/layout/view_bone_tab.xml | 4 +- .../src/main/res/layout/view_work_order.xml | 29 +- 14 files changed, 798 insertions(+), 66 deletions(-) create mode 100644 core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/MsgBoxBubbleView.kt create mode 100644 core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/MsgBoxBubbleAdapter.kt create mode 100644 core/function-impl/mogo-core-function-hmi/src/main/res/layout/layout_msg_box_bubble.xml diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/BadCaseManager.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/BadCaseManager.kt index d708e09133..8551afd4d0 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/BadCaseManager.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/BadCaseManager.kt @@ -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) +// } +// } } } diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/workorder/TakeOverReasonWindow.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/workorder/TakeOverReasonWindow.kt index cf3fee59b3..7aeebbfd84 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/workorder/TakeOverReasonWindow.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/workorder/TakeOverReasonWindow.kt @@ -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 } diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/drawable/bg_reason_list.xml b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable/bg_reason_list.xml index bfb99ae3be..7456a3cde6 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/res/drawable/bg_reason_list.xml +++ b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable/bg_reason_list.xml @@ -3,7 +3,7 @@ - + - + + android:radius="@dimen/dp_10"/> \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/layout/view_take_over_reason.xml b/core/function-impl/mogo-core-function-devatools/src/main/res/layout/view_take_over_reason.xml index bb97c8a3a4..0913255420 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/res/layout/view_take_over_reason.xml +++ b/core/function-impl/mogo-core-function-devatools/src/main/res/layout/view_take_over_reason.xml @@ -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" /> \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/BoneTabLayout.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/BoneTabLayout.kt index 2bb25033ac..177d0e00e9 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/BoneTabLayout.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/BoneTabLayout.kt @@ -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?) { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/FaultReasonView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/FaultReasonView.kt index 9b5ca28692..1bf14a8954 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/FaultReasonView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/FaultReasonView.kt @@ -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) } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/ReportTypeView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/ReportTypeView.kt index 430fc72531..253aec586e 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/ReportTypeView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/ReportTypeView.kt @@ -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) { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/WorkOrderView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/WorkOrderView.kt index 25fb89a38b..d47ece024e 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/WorkOrderView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/bone/tab/WorkOrderView.kt @@ -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 + } + } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/MsgBoxBubbleView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/MsgBoxBubbleView.kt new file mode 100644 index 0000000000..506fff2706 --- /dev/null +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/MsgBoxBubbleView.kt @@ -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 = 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) + } + +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/MsgBoxBubbleAdapter.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/MsgBoxBubbleAdapter.kt new file mode 100644 index 0000000000..2bb05b64b3 --- /dev/null +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/MsgBoxBubbleAdapter.kt @@ -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() { + + private var data: ArrayList ?= 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){ + 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) + } + +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/layout_msg_box_bubble.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/layout_msg_box_bubble.xml new file mode 100644 index 0000000000..e8a0ce25ed --- /dev/null +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/layout_msg_box_bubble.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_bone_tab.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_bone_tab.xml index af1410dfa0..fefbf2a188 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_bone_tab.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_bone_tab.xml @@ -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" /> - -