[6.7.0]数据闭环UI调整

This commit is contained in:
xuxinchao
2024-09-25 10:28:28 +08:00
parent d927a01ece
commit b08dd5cf20
23 changed files with 2055 additions and 16 deletions

View File

@@ -5,11 +5,11 @@
>
<!--内部填充-->
<solid android:color="#1AA7B6F0" />
<solid android:color="#19C1C1C1" />
<stroke
android:width="@dimen/dp_1"
android:color="#A7B6F0"
android:color="#A3A3A3"
/>
<corners android:radius="@dimen/dp_8"/>

View File

@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#0056FF"/>
<corners android:radius="@dimen/dp_8"/>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:startColor="#22C9F8"
android:endColor="#3E6DFC"
android:angle="270"
/>
<corners
android:radius="@dimen/dp_0"/>
</shape>

View File

@@ -5,13 +5,8 @@
>
<!--内部填充-->
<solid android:color="#1AA7B6F0" />
<solid android:color="#4D4D4D" />
<stroke
android:width="@dimen/dp_1"
android:color="#A7B6F0"
/>
<corners android:radius="@dimen/dp_8"/>
<corners android:radius="@dimen/dp_10"/>
</shape>

View File

@@ -4,7 +4,7 @@
<string name="work_order_report_title">问题上报</string>
<string name="work_order_type">问题类型</string>
<string name="work_order_occurrence_time">发生时间</string>
<string name="work_order_describe">问题描述</string>
<string name="work_order_describe">补充描述</string>
<string name="work_order_describe_input">手动输入</string>
<string name="work_order_report">上报</string>
<string name="work_order_cancel">取消</string>

View File

@@ -23,7 +23,6 @@
<item name="android:textSize">@dimen/sp_30</item>
<item name="android:background">@drawable/work_order_type_radio_button</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_margin">@dimen/dp_8</item>
</style>

View File

@@ -79,6 +79,7 @@ dependencies {
implementation rootProject.ext.dependencies.koomxhook
implementation rootProject.ext.dependencies.preference
implementation rootProject.ext.dependencies.preference_ktx
implementation rootProject.ext.dependencies.amapsearch
implementation rootProject.ext.dependencies.thread_opt
api project(':test:crashreport-apmbyte')

View File

@@ -8,16 +8,20 @@ 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.ReportTypeView
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
import kotlinx.android.synthetic.main.view_bone_tab.view.carInfoTabView
import kotlinx.android.synthetic.main.view_bone_tab.view.faultReasonView
import kotlinx.android.synthetic.main.view_bone_tab.view.msgBoxTabView
import kotlinx.android.synthetic.main.view_bone_tab.view.reportTypeView
import kotlinx.android.synthetic.main.view_bone_tab.view.tabSwitchCarInfo
import kotlinx.android.synthetic.main.view_bone_tab.view.tabSwitchMore
import kotlinx.android.synthetic.main.view_bone_tab.view.tabSwitchMsgBox
import kotlinx.android.synthetic.main.view_bone_tab.view.tabSwitchReport
import kotlinx.android.synthetic.main.view_bone_tab.view.toolKitTabView
import kotlinx.android.synthetic.main.view_bone_tab.view.workOrderView
import kotlin.properties.Delegates
class BoneTabLayout @JvmOverloads constructor(
@@ -83,6 +87,15 @@ class BoneTabLayout @JvmOverloads constructor(
logOut?.invoke()
}
reportTypeView.setClickListener(object: ReportTypeView.ClickListener{
override fun openFaultReasonView() {
faultReasonView.visibility = VISIBLE
}
override fun openWorkOrderView() {
workOrderView.visibility = VISIBLE
}
})
}
fun setCarNo(carNo: String?) {
@@ -132,9 +145,10 @@ class BoneTabLayout @JvmOverloads constructor(
TabType.REPORT_INFO -> {
tabSwitchReport.switchTab(check)
if (check) {
reportTypeView.visibility = VISIBLE
reportTypeView.showTypeSelectView()
} else {
reportTypeView.visibility = GONE
}
}

View File

@@ -0,0 +1,497 @@
package com.mogo.eagle.core.function.hmi.bone.tab
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.text.TextWatcher
import com.iflytek.cloud.ErrorCode
import com.iflytek.cloud.InitListener
import com.iflytek.cloud.RecognizerListener
import com.iflytek.cloud.RecognizerResult
import com.iflytek.cloud.SpeechError
import com.iflytek.cloud.SpeechRecognizer
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.animation.Animation
import android.view.animation.ScaleAnimation
import android.widget.EditText
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.report.CategoryInfo
import com.mogo.eagle.core.data.deva.report.PadAddProblemReq
import com.mogo.eagle.core.data.deva.report.PadProblemInfo
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.api.order.IOrderListener
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.JsonParser
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.tts.base.SpeechUtils
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.workorder.adapter.OrderReasonAdapter
import kotlinx.android.synthetic.main.view_fault_reason.view.etNoteInput
import kotlinx.android.synthetic.main.view_fault_reason.view.faultReasonGroup
import kotlinx.android.synthetic.main.view_fault_reason.view.ivNoteAudio
import kotlinx.android.synthetic.main.view_fault_reason.view.ivTimeAdd
import kotlinx.android.synthetic.main.view_fault_reason.view.ivTimeReduce
import kotlinx.android.synthetic.main.view_fault_reason.view.rvFaultList
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultCancel
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultReason
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultReport
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultTime
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultType
import kotlinx.android.synthetic.main.view_fault_reason.view.tvOccurrenceTime
import kotlinx.android.synthetic.main.view_fault_reason.view.tvUploadSuccess
/**
* 故障原因编辑视图
*/
class FaultReasonView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoDevaToolsListener, IOrderListener {
private val TAG = "FaultReasonView"
// 语音听写对象
private var mIat: SpeechRecognizer? = null
// 用HashMap存储听写结果
private val mIatResults: HashMap<String, String> = LinkedHashMap()
var ret = 0 // 函数调用返回值
private var audioStatus = false
private var workOrderOccurrenceTime = System.currentTimeMillis() //故障发生时间
private var clickListener: ClickListener? = null
private lateinit var orderReasonAdapter: OrderReasonAdapter
private var address: String = "" //故障地点
private var faultCodeList = ArrayList<String>() //故障码列表
private var level1Id: Int = 0 //一级分类ID
private var level2Id: Int = 0 //二级分类ID
private var level3Id: Int = 0 //三级分类ID
private var level1Name: String = ""
private var level2Name: String = ""
private var level3Name: String = ""
private var reportNote: String = "" //上报描述
private val reportType: Int = 1 //上报方式0小程序 1司机屏 2云端上报
private var source: Int = 0 //操作源0:默认,一级分类 1:类型二级分类2:原因,三级分类
private var hasLevel2: Boolean = false //是否有二级分类
private var hasLevel3: Boolean = false //是否有三级分类
private var typeList: List<CategoryInfo> ?= null //故障类型列表
private var reasonList: List<CategoryInfo> ?= null //故障原因列表
private var faultTypeSelectStatus: Boolean = false //故障类型选择状态
private var faultReasonSelectStatus: Boolean = false //故障原因选择状态
private val type = 1 //故障类接口请求Type值为1
init {
LayoutInflater.from(context).inflate(R.layout.view_fault_reason, this, true)
initView()
initEvent()
}
private fun initView(){
// 初始化识别无UI识别对象
// 使用SpeechRecognizer对象可根据回调消息自定义界面
mIat = SpeechRecognizer.createRecognizer(context, mInitListener)
val linearLayoutManager = LinearLayoutManager(context)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
rvFaultList.layoutManager = linearLayoutManager
orderReasonAdapter = OrderReasonAdapter()
orderReasonAdapter.setListener(object: OrderReasonAdapter.ReasonSelectListener{
override fun onSelectReason(reason: CategoryInfo, mSource: Int) {
if(mSource == 1){
//类型
tvFaultType.text = reason.name
//选择了故障类型
tvFaultType.performClick()
if(level2Id != 0 && level2Id == reason.id){
//故障类型选择没有变化
reasonList?.let { orderReasonAdapter.setData(it,2) }
}else{
//故障类型发生了变化
level2Id = reason.id
level2Name = reason.name
source = 2
//获取故障三级分类即故障原因
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,3,level2Id,type,0)
tvFaultReason.text = ""
level3Id = 0
level3Name = ""
}
}else{
//原因
tvFaultReason.text = reason.name
tvFaultReason.performClick()
level3Id = reason.id
level3Name = reason.name
}
}
})
rvFaultList.adapter = orderReasonAdapter
}
@SuppressLint("SetTextI18n")
private fun initEvent(){
CallerDevaToolsListenerManager.addListener(TAG, this)
CallerOrderListenerManager.addListener(TAG,this)
val iconDown = ContextCompat.getDrawable(context, R.drawable.icon_fault_expand)
iconDown?.setBounds(0, 0, iconDown.minimumWidth, iconDown.minimumHeight)
val iconUp = ContextCompat.getDrawable(context, R.drawable.icon_fault_retract)
iconUp?.setBounds(0, 0, iconUp.minimumWidth, iconUp.minimumHeight)
//获取一级分类
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,1,0,type,0)
//弹窗展示时间
tvFaultTime.text = millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())
//故障类型选择
tvFaultType.setOnClickListener {
if(!hasLevel2){
ToastUtils.showShort("运营后台没有配置故障类型")
return@setOnClickListener
}
if(faultTypeSelectStatus){
//关闭
faultTypeSelectStatus = false
tvFaultType.setCompoundDrawables(null, null, iconDown, null)
//隐藏列表
rvFaultList.visibility = View.GONE
}else{
//如果故障原因此时为打开状态,则关闭
if(faultReasonSelectStatus){
tvFaultReason.performClick()
}
//打开
faultTypeSelectStatus = true
tvFaultType.setCompoundDrawables(null, null, iconUp, null)
//展示列表
rvFaultList.visibility = View.VISIBLE
(rvFaultList.layoutParams as ConstraintLayout.LayoutParams).topToBottom = R.id.tvFaultType
source = 1
if(typeList.isNullOrEmpty()){
//获取故障二级分类即故障类型
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,2,level1Id,type,0)
}else{
orderReasonAdapter.setData(typeList!!,source)
}
}
}
//故障原因选择
tvFaultReason.setOnClickListener {
if(tvFaultType.text.isEmpty()){
ToastUtils.showShort("请先选择故障类型")
return@setOnClickListener
}
if(faultReasonSelectStatus){
//关闭
faultReasonSelectStatus = false
tvFaultReason.setCompoundDrawables(null, null, iconDown, null)
//隐藏列表
rvFaultList.visibility = View.GONE
}else{
//打开
faultReasonSelectStatus = true
tvFaultReason.setCompoundDrawables(null, null, iconUp, null)
//展示列表
rvFaultList.visibility = View.VISIBLE
(rvFaultList.layoutParams as ConstraintLayout.LayoutParams).topToBottom = R.id.tvFaultReason
}
}
//发生时间
tvOccurrenceTime.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
ivTimeReduce.setOnClickListener {
workOrderOccurrenceTime -= 60000
tvOccurrenceTime.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
}
ivTimeAdd.setOnClickListener {
if(workOrderOccurrenceTime + 60000 > System.currentTimeMillis()){
ToastUtils.showShort("发生时间应在当前时间之前")
return@setOnClickListener
}
workOrderOccurrenceTime += 60000
tvOccurrenceTime.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
}
//补充描述
etNoteInput.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
val edit = v as EditText
if(hasFocus){
edit.hint = ""
}else{
edit.hint = "手动输入"
}
}
etNoteInput.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
}
})
//问题描述录音
ivNoteAudio.setOnClickListener {
audioStatus = !audioStatus
if(audioStatus){
ivNoteAudio.setImageDrawable(ContextCompat.getDrawable(
context,
R.drawable.icon_reason_audio_pressed
))
}else{
ivNoteAudio.setImageDrawable(ContextCompat.getDrawable(
context,
R.drawable.icon_reason_audio_normal
))
}
setAudio(audioStatus)
}
//上报
tvFaultReport.setOnClickListener{
if(level2Name.isEmpty()){
ToastUtils.showShort("请完整填写再上报")
return@setOnClickListener
}
if(hasLevel3 && level3Name.isEmpty()){
ToastUtils.showShort("请完整填写再上报")
return@setOnClickListener
}
reportNote = etNoteInput.text.toString()
//故障码列表赋值
BadCaseConfig.newFMInfoMsg?.fmInfoList?.forEach {
faultCodeList.add(it.faultId)
}
val geocodeSearch = GeocodeSearch(context)
geocodeSearch.setOnGeocodeSearchListener(object: GeocodeSearch.OnGeocodeSearchListener {
override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult?, p1: Int) {
regeocodeResult?.regeocodeAddress?.formatAddress?.let {
address = it
}
val padProblemList= ArrayList<PadProblemInfo>()
val note = if(reportNote.isEmpty()){
"$level1Name-$level2Name-$level3Name"
}else{
"$level1Name-$level2Name-$level3Name($reportNote)"
}
val padProblemInfo = PadProblemInfo(address,faultCodeList,millis2String(workOrderOccurrenceTime),level1Id,
level2Id,level3Id,BadCaseConfig.lineName,note,reportType,
SharedPrefsMgr.getInstance().getString("och_account",""))
padProblemList.add(padProblemInfo)
val padAddProblemReq = PadAddProblemReq(padProblemList, AppConfigInfo.plateNumber)
CallerDevaToolsManager.problemPadAdd(padAddProblemReq)
}
override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
}
})
val latLon = LatLonPoint(CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().latitude, CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().longitude)
val q = RegeocodeQuery(latLon,200f,GeocodeSearch.AMAP)
geocodeSearch.getFromLocationAsyn(q)
}
//取消
tvFaultCancel.setOnClickListener {
this@FaultReasonView.visibility = View.GONE
}
}
private fun setAudio(status: Boolean){
if(status){
//开始录音
mIat?.let {
//清空之前的内容
mIatResults.clear()
SpeechUtils.setParam(it)
// 不显示听写对话框
ret = it.startListening(mRecognizerListener)
if (ret != ErrorCode.SUCCESS) {
ToastUtils.showShort("听写失败,错误码:$ret,请点击网址https://www.xfyun.cn/document/error-code查询解决方案")
}
}
//开始录音,展示放大缩小动效
val scaleAnimation = ScaleAnimation(
1.0f, 0.8f, 1.0f, 0.8f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f)
scaleAnimation.duration = 1000
scaleAnimation.repeatCount = -1
ivNoteAudio.startAnimation(scaleAnimation)
}else{
//停止语音听写
mIat?.stopListening()
//结束动画
ivNoteAudio.clearAnimation()
}
}
/**
* 初始化监听器。
*/
private val mInitListener = InitListener { code ->
if (code != ErrorCode.SUCCESS) {
ToastUtils.showShort("讯飞语音听写初始化失败,错误码:$code")
}
}
/**
* 听写监听器。
*/
private val mRecognizerListener: RecognizerListener = object : RecognizerListener{
override fun onVolumeChanged(p0: Int, p1: ByteArray?) {
//showTip("当前正在说话,音量大小 = " + volume + " 返回音频数据 = " + data.length);
}
override fun onBeginOfSpeech() {
// 此回调表示sdk内部录音机已经准备好了用户可以开始语音输入
}
override fun onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
}
override fun onResult(results: RecognizerResult?, isLast: Boolean) {
results?.let {
printResult(it)
}
}
override fun onError(p0: SpeechError?) {
// Tips
// 错误码10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
}
override fun onEvent(p0: Int, p1: Int, p2: Int, p3: Bundle?) {
// 以下代码用于获取与云端的会话id当业务出错时将会话id提供给技术支持人员可用于查询会话日志定位出错原因
// 若使用本地能力会话id为null
// if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
// }
}
}
/**
* 显示结果
*/
@SuppressLint("SetTextI18n")
private fun printResult(results: RecognizerResult) {
val text: String = JsonParser.parseIatResult(results.resultString)
Log.i(TAG, "语音内容=$text")
if(text.isNotEmpty()){
if(etNoteInput.text.toString().isEmpty()){
etNoteInput.setText(text)
etNoteInput.setSelection(text.length)
}else{
val startStr = etNoteInput.text.toString().substring(0,etNoteInput.selectionStart)
val endStr = etNoteInput.text.toString().substring(etNoteInput.selectionEnd,etNoteInput.text.toString().length)
etNoteInput.setText(startStr+text+endStr)
etNoteInput.setSelection(startStr.length+text.length)
}
}
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
interface ClickListener {
fun closeWindow()
}
/**
* 故障上报成功
*/
override fun problemPadAddSuccess() {
super.problemPadAddSuccess()
//显示上报成功页面,短暂停留关闭弹窗
ThreadUtils.runOnUiThread {
//结束动画
ivNoteAudio.clearAnimation()
rvFaultList.visibility = View.GONE
tvUploadSuccess.visibility = View.VISIBLE
faultReasonGroup.visibility = View.GONE
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this@FaultReasonView.visibility = View.GONE
},1500)
}
}
override fun problemPadAddError(msg: String) {
super.problemPadAddError(msg)
ToastUtils.showShort("故障原因上报失败$msg")
}
override fun getCategoriesSuccess(list: List<CategoryInfo>) {
super.getCategoriesSuccess(list)
ThreadUtils.runOnUiThread {
if(list.isNotEmpty()){
if(source == 0){
level1Id = list[0].id
level1Name = list[0].name
source = 1
//获取故障二级分类即故障类型
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,2,level1Id,type,0)
}else{
if(source == 1){
typeList = list
hasLevel2 = true
}else{
reasonList = list
hasLevel3 = true
}
orderReasonAdapter.setData(list,source)
}
}else{
if(source == 2){
hasLevel3 = false
}else{
hasLevel2 = false
ToastUtils.showShort("故障类型列表为空")
}
}
}
}
override fun getCategoriesError(msg: String) {
super.getCategoriesError(msg)
ToastUtils.showShort("故障列表获取失败:$msg")
}
}

View File

@@ -0,0 +1,261 @@
package com.mogo.eagle.core.function.hmi.bone.tab
import android.content.Context
import android.os.CountDownTimer
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import com.mogo.commons.env.ProjectUtils
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.report.CategoryInfo
import com.mogo.eagle.core.data.deva.report.PadAddProblemReq
import com.mogo.eagle.core.data.deva.report.PadProblemInfo
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import kotlinx.android.synthetic.main.view_report_type.view.ivOneClickReport
import kotlinx.android.synthetic.main.view_report_type.view.oneClickGroup
import kotlinx.android.synthetic.main.view_report_type.view.reportTypeGroup
import kotlinx.android.synthetic.main.view_report_type.view.tvOneClickReportTitle
import kotlinx.android.synthetic.main.view_report_type.view.tvReportSuccess
import kotlinx.android.synthetic.main.view_report_type.view.tvReportTypeFault
import kotlinx.android.synthetic.main.view_report_type.view.tvReportTypeTakeOver
import kotlin.math.absoluteValue
import kotlin.math.round
import kotlin.random.Random
/**
* 上报类型选择,包括一键上报及上报类型选择:故障类、接管类
* 一键上报和类型选择互斥,当点击弹出上报类型选择时,一键上报隐藏
*/
class ReportTypeView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoDevaToolsListener {
private val TAG = "ReportTypeView"
private var isOneClickType: Boolean = false //是否是一键上报类型
private var hasReportOperate: Boolean = false //是否点击了一键上报按钮
private var oneClickTimer: CountDownTimer?= null
private var clickListener: ClickListener? = null
private var address: String = "" //故障地点
private var faultCodeList = ArrayList<String>() //故障码列表
private var level1Id: Int = 0 //一级分类ID
private var level2Id: Int = 0 //二级分类ID
private var level3Id: Int = 0 //三级分类ID
private var level1Name: String = ""
private var level2Name: String = ""
private var level3Name: String = ""
private val reportType: Int = 1 //上报方式0小程序 1司机屏 2云端上报
private var level: Int = 1
private var canOneReport: Boolean = false //是否可以一键上报
init {
LayoutInflater.from(context).inflate(R.layout.view_report_type, this, true)
initView()
}
private fun initView(){
CallerDevaToolsListenerManager.addListener(TAG, this)
if(isOneClickType){
showOneCLickReportView()
}else{
showTypeSelectView()
}
//一键上报
ivOneClickReport.setOnClickListener {
if(!canOneReport){
ToastUtils.showShort("故障描述获取失败不能上报")
return@setOnClickListener
}
hasReportOperate = true
BadCaseConfig.newFMInfoMsg?.fmInfoList?.forEach {
faultCodeList.add(it.faultId)
}
val geocodeSearch = GeocodeSearch(context)
geocodeSearch.setOnGeocodeSearchListener(object: GeocodeSearch.OnGeocodeSearchListener {
override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult?, p1: Int) {
regeocodeResult?.regeocodeAddress?.formatAddress?.let {
address = it
}
val padProblemList= ArrayList<PadProblemInfo>()
val padProblemInfo = PadProblemInfo(address,faultCodeList,millis2String(System.currentTimeMillis()),level1Id,
level2Id,level3Id,BadCaseConfig.lineName,"${level1Name}-${level2Name}-${level3Name}",reportType,
SharedPrefsMgr.getInstance().getString("och_account",""))
padProblemList.add(padProblemInfo)
val padAddProblemReq = PadAddProblemReq(padProblemList, AppConfigInfo.plateNumber)
CallerDevaToolsManager.problemPadAdd(padAddProblemReq)
}
override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
}
})
val latLon = LatLonPoint(CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().latitude, CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().longitude)
val q = RegeocodeQuery(latLon,200f, GeocodeSearch.AMAP)
geocodeSearch.getFromLocationAsyn(q)
}
//故障类
tvReportTypeFault.setOnClickListener {
//TODO 更改!
if(!ProjectUtils.isSaas()){
clickListener?.openFaultReasonView()
}else{
//展示工单上报弹窗
clickListener?.openWorkOrderView()
}
this@ReportTypeView.visibility = View.GONE
}
//主动录包
tvReportTypeTakeOver.setOnClickListener {
val response = CallerAutoPilotControlManager.recordPackage(
BadCaseConfig.type, Random(SystemClock.elapsedRealtime()).nextInt().absoluteValue,
BadCaseConfig.totalDuration, BadCaseConfig.previousDuration)
if(response){
//已发起录包
oneClickGroup.visibility = View.GONE
reportTypeGroup.visibility = View.GONE
tvReportSuccess.visibility = View.VISIBLE
tvReportSuccess.text = resources.getString(R.string.record_success)
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this@ReportTypeView.visibility = View.GONE
},1500)
}else{
ToastUtils.showShort("主动录包命令下发失败")
this@ReportTypeView.visibility = View.GONE
}
}
}
/**
* 展示一键上报视图
*/
private fun showOneCLickReportView(){
oneClickGroup.visibility = View.VISIBLE
reportTypeGroup.visibility = View.GONE
tvReportSuccess.visibility = View.GONE
tvOneClickReportTitle.text = String.format(resources.getString(R.string.identified_vehicle_malfunction),5)
oneClickTimer = object : CountDownTimer(5000, 1000) {
override fun onTick(count: Long) {
ThreadUtils.runOnUiThread {
tvOneClickReportTitle.text = String.format(resources.getString(R.string.identified_vehicle_malfunction),round((count.toDouble()/1000)).toInt())
}
}
override fun onFinish() {
//如果有页面操作,则不自动关闭窗口
if(!hasReportOperate){
ThreadUtils.runOnUiThread {
this@ReportTypeView.visibility = View.GONE
}
}
}
}
oneClickTimer?.start()
}
/**
* 展示类型选择视图
*/
fun showTypeSelectView(){
oneClickGroup.visibility = View.GONE
reportTypeGroup.visibility = View.VISIBLE
tvReportSuccess.visibility = View.GONE
}
/**
* 故障上报成功
*/
override fun problemPadAddSuccess() {
//显示上报成功页面,短暂停留关闭弹窗
ThreadUtils.runOnUiThread {
oneClickGroup.visibility = View.GONE
reportTypeGroup.visibility = View.GONE
tvReportSuccess.visibility = View.VISIBLE
tvReportSuccess.text = resources.getString(R.string.report_success)
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this.visibility = View.GONE
},1500)
}
}
override fun problemPadAddError(msg: String) {
super.problemPadAddError(msg)
ToastUtils.showShort("故障原因上报失败$msg")
ThreadUtils.runOnUiThread {
this.visibility = View.GONE
}
}
override fun getCategoriesSuccess(list: List<CategoryInfo>) {
super.getCategoriesSuccess(list)
if(list.isEmpty()){
ToastUtils.showShort("一键上报故障描述后台未配置")
canOneReport = false
}else{
when (level) {
1 -> {
level1Id = list[0].id
level1Name = list[0].name
level = 2
//请求二级一键上报配置
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,level,level1Id,4,1)
}
2 -> {
level2Id = list[0].id
level2Name = list[0].name
level = 3
//请求三级一键上报配置
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,level,level2Id,4,1)
}
else -> {
level3Id = list[0].id
level3Name = list[0].name
canOneReport = true
}
}
}
}
override fun getCategoriesError(msg: String) {
super.getCategoriesError(msg)
ToastUtils.showShort("一键上报故障描述获取失败$msg")
canOneReport = false
}
interface ClickListener {
fun openFaultReasonView()
fun openWorkOrderView()
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
}

View File

@@ -0,0 +1,312 @@
package com.mogo.eagle.core.function.hmi.bone.tab
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.animation.Animation
import android.view.animation.ScaleAnimation
import android.widget.EditText
import androidx.constraintlayout.widget.ConstraintLayout
import com.iflytek.cloud.ErrorCode
import com.iflytek.cloud.InitListener
import com.iflytek.cloud.RecognizerListener
import com.iflytek.cloud.RecognizerResult
import com.iflytek.cloud.SpeechError
import com.iflytek.cloud.SpeechRecognizer
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.report.FaultDetailInfo
import com.mogo.eagle.core.data.deva.report.FaultInfo
import com.mogo.eagle.core.data.deva.report.WorkOrderReportInfo
import com.mogo.eagle.core.data.msgbox.FMInfoMsg
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.JsonParser
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.tts.base.SpeechUtils
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import kotlinx.android.synthetic.main.view_work_order.view.et_describe_input
import kotlinx.android.synthetic.main.view_work_order.view.iv_describe_audio
import kotlinx.android.synthetic.main.view_work_order.view.iv_time_add
import kotlinx.android.synthetic.main.view_work_order.view.iv_time_reduce
import kotlinx.android.synthetic.main.view_work_order.view.tv_occurrence_time
import kotlinx.android.synthetic.main.view_work_order.view.tv_work_order_cancel
import kotlinx.android.synthetic.main.view_work_order.view.tv_work_order_report
import kotlinx.android.synthetic.main.view_work_order.view.tv_work_order_time
import kotlinx.android.synthetic.main.view_work_order.view.wrap_radio_group
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
/**
* 工单上报视图
*/
class WorkOrderView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoDevaToolsListener {
private val TAG = "WorkOrderView"
// 语音听写对象
private var mIat: SpeechRecognizer? = null
// 用HashMap存储听写结果
private val mIatResults: HashMap<String, String> = LinkedHashMap()
private var workOrderType = "" //工单问题类型
private var workOrderOccurrenceTime = System.currentTimeMillis() //故障发生时间
var ret = 0 // 函数调用返回值
private var audioStatus = false
init {
LayoutInflater.from(context).inflate(R.layout.view_work_order, this, true)
initView()
initEvent()
}
private fun initView(){
// 初始化识别无UI识别对象
// 使用SpeechRecognizer对象可根据回调消息自定义界面
mIat = SpeechRecognizer.createRecognizer(context, mInitListener)
}
@OptIn(DelicateCoroutinesApi::class)
@SuppressLint("SetTextI18n")
private fun initEvent(){
CallerDevaToolsListenerManager.addListener(TAG, this)
//弹窗展示时间
tv_work_order_time.text = resources.getString(R.string.work_order_time) +
millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())
wrap_radio_group.setOnCheckedChangeListener{_, checkedId ->
when(checkedId){
R.id.rb_type_software->{
workOrderType = "软件"
}
R.id.rb_type_kit->{
workOrderType = "套件"
}
R.id.rb_type_vehicle->{
workOrderType = "车辆"
}
R.id.rb_type_capacity->{
workOrderType = "运力"
}
R.id.rb_type_environment->{
workOrderType = "环境"
}
R.id.rb_type_other->{
workOrderType = "其他"
}
}
}
//发生时间
tv_occurrence_time.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
iv_time_reduce.setOnClickListener {
workOrderOccurrenceTime -= 60000
tv_occurrence_time.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
}
iv_time_add.setOnClickListener {
if(workOrderOccurrenceTime + 60000 > System.currentTimeMillis()){
ToastUtils.showShort("发生时间应在当前时间之前")
return@setOnClickListener
}
workOrderOccurrenceTime += 60000
tv_occurrence_time.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
}
et_describe_input.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
val edit = v as EditText
if(hasFocus){
edit.hint = ""
}else{
edit.hint = "手动输入"
}
}
et_describe_input.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
}
})
//问题描述录音
iv_describe_audio.setOnClickListener {
audioStatus = !audioStatus
setAudio(audioStatus)
}
//上报
tv_work_order_report.setOnClickListener {
//工单问题类型必选,没有选择,进行提示
if(workOrderType.isEmpty()){
ToastUtils.showShort("请选择问题类型")
return@setOnClickListener
}
if(et_describe_input.text.toString().isEmpty()){
ToastUtils.showShort("请填写问题描述")
return@setOnClickListener
}
GlobalScope.launch(Dispatchers.IO){
val msgBoxList = CallerMsgBoxManager.queryFMInfoList(context,
workOrderOccurrenceTime-120000,workOrderOccurrenceTime+120000)
val faultList = ArrayList<FaultInfo>()
msgBoxList?.forEach { msgBoxBean ->
val fmInfoMsg = msgBoxBean.bean as FMInfoMsg
fmInfoMsg.fmInfoList?.forEach { fault ->
val faultBean = FaultInfo(false,fault.faultId,fault.faultName,
fault.faultTime.toString(), FaultDetailInfo(fault.faultDesc)
)
faultList.add(faultBean)
}
}
val workOrderReportInfo = WorkOrderReportInfo(workOrderType,workOrderOccurrenceTime.toString(),
et_describe_input.text.toString(), CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().longitude.toString(),
CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().latitude.toString(),
AppConfigInfo.plateNumber, SharedPrefsMgr.getInstance().getString("och_account","") ,
BadCaseConfig.dockerVersion ?:"",faultList)
CallerDevaToolsManager.workOrderReport(workOrderReportInfo)
}
}
//取消
tv_work_order_cancel.setOnClickListener {
this@WorkOrderView.visibility = View.GONE
}
}
private fun setAudio(status: Boolean){
if(status){
//开始录音
mIat?.let {
//清空之前的内容
mIatResults.clear()
SpeechUtils.setParam(it)
// 不显示听写对话框
ret = it.startListening(mRecognizerListener)
if (ret != ErrorCode.SUCCESS) {
ToastUtils.showShort("听写失败,错误码:$ret,请点击网址https://www.xfyun.cn/document/error-code查询解决方案")
}
}
//开始录音,展示放大缩小动效
val scaleAnimation = ScaleAnimation(
1.0f, 0.8f, 1.0f, 0.8f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f
)
scaleAnimation.duration = 1000
scaleAnimation.repeatCount = -1
iv_describe_audio.startAnimation(scaleAnimation)
}else{
//停止语音听写
mIat?.stopListening()
//结束动画
iv_describe_audio.clearAnimation()
}
}
/**
* 初始化监听器。
*/
private val mInitListener = InitListener { code ->
if (code != ErrorCode.SUCCESS) {
ToastUtils.showShort("讯飞语音听写初始化失败,错误码:$code")
}
}
/**
* 听写监听器。
*/
private val mRecognizerListener: RecognizerListener = object : RecognizerListener {
override fun onVolumeChanged(p0: Int, p1: ByteArray?) {
//showTip("当前正在说话,音量大小 = " + volume + " 返回音频数据 = " + data.length);
}
override fun onBeginOfSpeech() {
// 此回调表示sdk内部录音机已经准备好了用户可以开始语音输入
}
override fun onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
}
override fun onResult(results: RecognizerResult?, isLast: Boolean) {
results?.let {
printResult(it)
}
}
override fun onError(p0: SpeechError?) {
// Tips
// 错误码10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
}
override fun onEvent(p0: Int, p1: Int, p2: Int, p3: Bundle?) {
// 以下代码用于获取与云端的会话id当业务出错时将会话id提供给技术支持人员可用于查询会话日志定位出错原因
// 若使用本地能力会话id为null
// if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
// }
}
}
/**
* 显示结果
*/
@SuppressLint("SetTextI18n")
private fun printResult(results: RecognizerResult) {
val text: String = JsonParser.parseIatResult(results.resultString)
Log.i(TAG, "语音内容=$text")
if(text.isNotEmpty()){
if(et_describe_input.text.toString().isEmpty()){
et_describe_input.setText(text)
et_describe_input.setSelection(text.length)
}else{
val startStr = et_describe_input.text.toString().substring(0,et_describe_input.selectionStart)
val endStr = et_describe_input.text.toString().substring(et_describe_input.selectionEnd,et_describe_input.text.toString().length)
et_describe_input.setText(startStr+text+endStr)
et_describe_input.setSelection(startStr.length+text.length)
}
}
}
override fun workOrderReportSuccess() {
ToastUtils.showShort("工单上报成功")
ThreadUtils.runOnUiThread {
this@WorkOrderView.visibility = View.GONE
}
}
override fun workOrderReportError() {
ToastUtils.showShort("工单上报失败")
}
}

View File

@@ -0,0 +1,120 @@
package com.mogo.eagle.core.function.hmi.ui.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RadioGroup;
public class WrapRadioGroup extends RadioGroup {
public WrapRadioGroup(Context context) {
super(context);
}
public WrapRadioGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//调用ViewGroup的方法测量子view
measureChildren(widthMeasureSpec, heightMeasureSpec);
//最大的宽
int maxWidth = 0;
//累计的高
int totalHeight = 0;
//当前这一行的累计行宽
int lineWidth = 0;
//当前这行的最大行高
int maxLineHeight = 0;
//用于记录换行前的行宽和行高
int oldHeight;
int oldWidth;
int count = getChildCount();
//假设 widthMode和heightMode都是AT_MOST
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
//得到这一行的最高
oldHeight = maxLineHeight;
//当前最大宽度
oldWidth = maxWidth;
int deltaX = child.getMeasuredWidth() + params.leftMargin + params.rightMargin;
if (lineWidth + deltaX + getPaddingLeft() + getPaddingRight() > widthSize) {//如果折行,height增加
//和目前最大的宽度比较,得到最宽。不能加上当前的child的宽,所以用的是oldWidth
maxWidth = Math.max(lineWidth, oldWidth);
//重置宽度
lineWidth = deltaX;
//累加高度
totalHeight += oldHeight;
//重置行高,当前这个View属于下一行因此当前最大行高为这个child的高度加上margin
maxLineHeight = child.getMeasuredHeight() + params.topMargin + params.bottomMargin;
// Log.v(TAG, "maxHeight:" + totalHeight + "---" + "maxWidth:" + maxWidth);
} else {
//不换行,累加宽度
lineWidth += deltaX;
//不换行,计算行最高
int deltaY = child.getMeasuredHeight() + params.topMargin + params.bottomMargin;
maxLineHeight = Math.max(maxLineHeight, deltaY);
}
if (i == count - 1) {
//前面没有加上下一行的搞,如果是最后一行,还要再叠加上最后一行的最高的值
totalHeight += maxLineHeight;
//计算最后一行和前面的最宽的一行比较
maxWidth = Math.max(lineWidth, oldWidth);
}
}
//加上当前容器的padding值
maxWidth += getPaddingLeft() + getPaddingRight();
totalHeight += getPaddingTop() + getPaddingBottom();
setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : maxWidth,
heightMode == MeasureSpec.EXACTLY ? heightSize : totalHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
//pre为前面所有的child的相加后的位置
int preLeft = getPaddingLeft();
int preTop = getPaddingTop();
//记录每一行的最高值
int maxHeight = 0;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
//r-l为当前容器的宽度。如果子view的累积宽度大于容器宽度就换行。
if (preLeft + params.leftMargin + child.getMeasuredWidth() + params.rightMargin + getPaddingRight() > (r - l)) {
//重置
preLeft = getPaddingLeft();
//要选择child的height最大的作为设置
preTop = preTop + maxHeight;
maxHeight = getChildAt(i).getMeasuredHeight() + params.topMargin + params.bottomMargin;
} else { //不换行,计算最大高度
maxHeight = Math.max(maxHeight, child.getMeasuredHeight() + params.topMargin + params.bottomMargin);
}
//left坐标
int left = preLeft + params.leftMargin;
//top坐标
int top = preTop + params.topMargin;
int right = left + child.getMeasuredWidth();
int bottom = top + child.getMeasuredHeight();
//为子view布局
child.layout(left, top, right, bottom);
//计算布局结束后preLeft的值
preLeft += params.leftMargin + child.getMeasuredWidth() + params.rightMargin;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#4C000000"
android:endColor="#4C000000"
/>
<corners android:radius="@dimen/dp_10" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:startColor="#22C9F8"
android:endColor="#3E6DFC"
android:angle="270"
/>
<corners
android:radius="@dimen/dp_0"/>
</shape>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#19FFCB"
android:endColor="#1970FF"
android:angle="315"
/>
<corners android:radius="@dimen/dp_10" />
</shape>

View File

@@ -33,6 +33,40 @@
app:layout_constraintTop_toTopOf="parent"
/>
<com.mogo.eagle.core.function.hmi.bone.tab.ReportTypeView
android:id="@+id/reportTypeView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
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"
/>
<com.mogo.eagle.core.function.hmi.bone.tab.FaultReasonView
android:id="@+id/faultReasonView"
android:layout_width="@dimen/dp_960"
android:layout_height="@dimen/dp_1137"
android:layout_marginStart="@dimen/dp_40"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<com.mogo.eagle.core.function.hmi.bone.tab.WorkOrderView
android:id="@+id/workOrderView"
android:layout_width="@dimen/dp_960"
android:layout_height="@dimen/dp_1137"
android:layout_marginStart="@dimen/dp_40"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<com.mogo.eagle.core.function.hmi.bone.tab.ToolKitTabView
android:id="@+id/toolKitTabView"
android:layout_width="@dimen/dp_960"

View File

@@ -0,0 +1,343 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/bg_tab_item">
<View
android:id="@+id/viewTitleBg"
android:layout_width="@dimen/dp_856"
android:layout_height="@dimen/dp_100"
android:layout_marginTop="@dimen/dp_21"
android:layout_marginEnd="@dimen/dp_40"
android:background="@drawable/bg_tab_view_top"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<TextView
android:id="@+id/tvFaultTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_reason"
android:textSize="@dimen/sp_40"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewTitleBg"
app:layout_constraintBottom_toBottomOf="@id/viewTitleBg"
app:layout_constraintStart_toStartOf="@id/viewTitleBg"
android:layout_marginStart="@dimen/dp_32"
/>
<TextView
android:id="@+id/tvFaultTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_open_time"
android:textColor="@color/white"
android:textSize="@dimen/sp_32"
app:layout_constraintTop_toTopOf="@id/viewTitleBg"
app:layout_constraintBottom_toBottomOf="@id/viewTitleBg"
app:layout_constraintEnd_toEndOf="@id/viewTitleBg"
android:layout_marginEnd="@dimen/dp_30"
/>
<View
android:id="@+id/viewFaultTypeLabel"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="@drawable/bg_fault_reason_title_label"
app:layout_constraintTop_toBottomOf="@id/viewTitleBg"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
/>
<TextView
android:id="@+id/tvTypeTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_type"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewFaultTypeLabel"
app:layout_constraintBottom_toBottomOf="@id/viewFaultTypeLabel"
app:layout_constraintLeft_toRightOf="@id/viewFaultTypeLabel"
android:layout_marginStart="@dimen/dp_14"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvFaultType"
android:layout_width="@dimen/dp_781"
android:layout_height="@dimen/dp_70"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvTypeTitle"
android:layout_marginTop="@dimen/dp_14"
android:background="@drawable/bg_fault_type"
android:elevation="@dimen/dp_10"
android:textSize="@dimen/sp_30"
android:gravity="start|center_vertical"
android:textColor="@color/white"
android:paddingStart="@dimen/dp_21"
android:paddingEnd="@dimen/dp_21"
app:drawableEndCompat="@drawable/icon_fault_expand"
/>
<View
android:id="@+id/viewFaultReasonLabel"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="@drawable/bg_fault_reason_title_label"
app:layout_constraintTop_toBottomOf="@id/tvFaultType"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
/>
<TextView
android:id="@+id/tvFaultReasonTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_reason"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewFaultReasonLabel"
app:layout_constraintBottom_toBottomOf="@id/viewFaultReasonLabel"
app:layout_constraintLeft_toRightOf="@id/viewFaultReasonLabel"
android:layout_marginStart="@dimen/dp_14"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvFaultReason"
android:layout_width="@dimen/dp_781"
android:layout_height="@dimen/dp_70"
android:background="@drawable/bg_fault_type"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvFaultReasonTitle"
android:layout_marginTop="@dimen/dp_14"
android:paddingStart="@dimen/dp_21"
android:paddingEnd="@dimen/dp_21"
app:drawableEndCompat="@drawable/icon_fault_expand"
android:textSize="@dimen/sp_30"
android:textColor="@color/white"
android:gravity="center_vertical"
/>
<View
android:id="@+id/viewFaultTimeLabel"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="@drawable/bg_fault_reason_title_label"
app:layout_constraintTop_toBottomOf="@id/tvFaultReason"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
/>
<TextView
android:id="@+id/tvFaultTimeTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_time"
android:textSize="@dimen/sp_32"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewFaultTimeLabel"
app:layout_constraintBottom_toBottomOf="@id/viewFaultTimeLabel"
app:layout_constraintLeft_toRightOf="@id/viewFaultTimeLabel"
android:layout_marginStart="@dimen/dp_14"
/>
<View
android:id="@+id/viewTimeBg"
android:layout_width="@dimen/dp_295"
android:layout_height="@dimen/dp_72"
app:layout_constraintLeft_toLeftOf="@id/viewFaultTimeLabel"
app:layout_constraintTop_toBottomOf="@id/tvFaultTimeTitle"
android:layout_marginTop="@dimen/dp_15"
android:background="@drawable/bg_fault_type"
/>
<ImageView
android:id="@+id/ivTimeReduce"
android:layout_width="@dimen/dp_72"
android:layout_height="@dimen/dp_72"
android:src="@drawable/icon_fault_time_reduce"
app:layout_constraintTop_toTopOf="@id/viewTimeBg"
app:layout_constraintBottom_toBottomOf="@id/viewTimeBg"
app:layout_constraintLeft_toLeftOf="@id/viewTimeBg"
android:contentDescription="@string/fault_time_reduce"
/>
<ImageView
android:id="@+id/ivTimeAdd"
android:layout_width="@dimen/dp_72"
android:layout_height="@dimen/dp_72"
android:src="@drawable/icon_fault_time_add"
app:layout_constraintTop_toTopOf="@id/viewTimeBg"
app:layout_constraintBottom_toBottomOf="@id/viewTimeBg"
app:layout_constraintRight_toRightOf="@id/viewTimeBg"
android:contentDescription="@string/fault_time_add"
/>
<TextView
android:id="@+id/tvOccurrenceTime"
android:layout_width="@dimen/dp_0"
android:layout_height="@dimen/dp_0"
android:textSize="@dimen/sp_30"
android:textColor="@color/white"
android:gravity="center"
android:background="#1AA7B6F0"
app:layout_constraintTop_toTopOf="@id/viewTimeBg"
app:layout_constraintBottom_toBottomOf="@id/viewTimeBg"
app:layout_constraintLeft_toRightOf="@id/ivTimeReduce"
app:layout_constraintRight_toLeftOf="@id/ivTimeAdd"
/>
<View
android:id="@+id/viewFaultNoteLabel"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="@drawable/bg_fault_reason_title_label"
app:layout_constraintTop_toBottomOf="@id/viewTimeBg"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
/>
<TextView
android:id="@+id/tvFaultNoteTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_note"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewFaultNoteLabel"
app:layout_constraintBottom_toBottomOf="@id/viewFaultNoteLabel"
app:layout_constraintLeft_toRightOf="@id/viewFaultNoteLabel"
android:layout_marginStart="@dimen/dp_14"
/>
<TextView
android:id="@+id/tvFaultNoteSupplement"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tvFaultNoteTitle"
app:layout_constraintBottom_toBottomOf="@id/tvFaultNoteTitle"
app:layout_constraintLeft_toRightOf="@id/tvFaultNoteTitle"
android:text="@string/fault_note_supplement"
android:textSize="@dimen/sp_30"
android:textColor="#CCCCCC"
/>
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/etNoteInput"
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_115"
app:layout_constraintTop_toBottomOf="@id/viewFaultNoteLabel"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:hint="@string/take_over_note_input"
android:textColorHint="#A3ABC0"
android:textCursorDrawable="@drawable/work_order_input_cursor"
android:textSize="@dimen/sp_30"
android:textColor="@color/white"
android:gravity="top|start"
android:paddingStart="@dimen/dp_28"
android:paddingTop="@dimen/dp_21"
android:paddingEnd="@dimen/dp_80"
android:layout_marginTop="@dimen/dp_25"
android:background="@drawable/bg_fault_des_input"
/>
<ImageView
android:id="@+id/ivNoteAudio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_reason_audio_normal"
app:layout_constraintTop_toTopOf="@id/etNoteInput"
app:layout_constraintBottom_toBottomOf="@id/etNoteInput"
app:layout_constraintEnd_toEndOf="@id/etNoteInput"
android:padding="@dimen/dp_30"
android:contentDescription="@string/take_over_note_audio"
/>
<TextView
android:id="@+id/tvFaultReport"
android:layout_width="@dimen/dp_380"
android:layout_height="@dimen/dp_80"
app:layout_constraintLeft_toLeftOf="@id/etNoteInput"
app:layout_constraintTop_toBottomOf="@id/etNoteInput"
android:layout_marginTop="@dimen/dp_39"
android:background="@drawable/bg_fault_report"
android:text="@string/fault_report"
android:textColor="#FFFFFF"
android:textSize="@dimen/sp_32"
android:textStyle="bold"
android:gravity="center"
/>
<TextView
android:id="@+id/tvFaultCancel"
android:layout_width="@dimen/dp_380"
android:layout_height="@dimen/dp_80"
app:layout_constraintRight_toRightOf="@id/etNoteInput"
app:layout_constraintTop_toBottomOf="@id/etNoteInput"
android:layout_marginTop="@dimen/dp_39"
android:text="@string/take_over_cancel"
android:textColor="#FFFFFF"
android:textSize="@dimen/sp_32"
android:textStyle="bold"
android:gravity="center"
android:background="@drawable/bg_fault_cancel"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvFaultList"
android:layout_width="@dimen/dp_0"
android:layout_height="@dimen/dp_0"
app:layout_constraintLeft_toLeftOf="@id/tvFaultType"
app:layout_constraintRight_toRightOf="@id/tvFaultType"
app:layout_constraintTop_toBottomOf="@id/tvFaultType"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/dp_39"
android:background="@drawable/bg_reason_list"
android:visibility="gone"
android:layout_marginTop="@dimen/dp_m_5"
android:paddingTop="@dimen/dp_5"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvUploadSuccess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_406"
app:drawableTopCompat="@drawable/icon_take_over_upload_success"
android:text="@string/report_success"
android:textColor="@color/white"
android:textSize="@dimen/sp_32"
android:drawablePadding="@dimen/dp_40"
android:visibility="gone"
/>
<androidx.constraintlayout.widget.Group
android:id="@+id/faultReasonGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="viewFaultTypeLabel,tvTypeTitle,tvFaultType,
viewFaultReasonLabel,tvFaultReasonTitle,viewFaultTimeLabel,
tvFaultTimeTitle,ivTimeReduce,tvOccurrenceTime,ivTimeAdd,
viewFaultNoteLabel,tvFaultNoteTitle,tvFaultNoteSupplement,
etNoteInput,ivNoteAudio,tvFaultReport,tvFaultCancel,tvFaultReason"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/dp_501"
android:layout_height="@dimen/dp_379"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/bg_tab_report_type">
<TextView
android:id="@+id/tvOneClickReportTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:layout_marginTop="@dimen/dp_67"
android:text="@string/identified_vehicle_malfunction"
/>
<ImageView
android:id="@+id/ivOneClickReport"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/icon_one_click_report"
android:layout_marginTop="@dimen/dp_157"
android:contentDescription="@string/one_click_report"
/>
<androidx.constraintlayout.widget.Group
android:id="@+id/oneClickGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="tvOneClickReportTitle,ivOneClickReport"
/>
<TextView
android:id="@+id/tvReportTypeTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text="@string/report_type"
android:textColor="@color/white"
android:textSize="@dimen/sp_38"
android:layout_marginTop="@dimen/dp_50"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvReportTypeFault"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:text="@string/report_type_fault"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
app:drawableTopCompat="@drawable/icon_type_fault"
android:drawablePadding="@dimen/dp_3"
android:layout_marginLeft="@dimen/dp_110"
android:layout_marginTop="@dimen/dp_118"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvReportTypeTakeOver"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text="@string/report_type_take_over"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
app:drawableTopCompat="@drawable/icon_type_take_over"
android:drawablePadding="@dimen/dp_3"
android:layout_marginTop="@dimen/dp_118"
android:layout_marginRight="@dimen/dp_90"
/>
<View
android:id="@+id/viewDivider"
android:layout_width="@dimen/dp_1"
android:layout_height="@dimen/dp_0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/tvReportTypeFault"
app:layout_constraintBottom_toBottomOf="@id/tvReportTypeFault"
android:background="@color/white"
/>
<androidx.constraintlayout.widget.Group
android:id="@+id/reportTypeGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="tvReportTypeTitle,tvReportTypeFault,tvReportTypeTakeOver,viewDivider"
android:visibility="visible"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvReportSuccess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/report_success"
android:textSize="@dimen/sp_26"
android:textColor="@color/white"
app:drawableTopCompat="@drawable/icon_report_success"
android:layout_marginTop="@dimen/dp_79"
android:drawablePadding="@dimen/dp_22"
android:visibility="gone"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,309 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.widget.RoundConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_tab_item">
<View
android:id="@+id/view_title_bg"
android:layout_width="@dimen/dp_856"
android:layout_height="@dimen/dp_100"
android:layout_marginTop="@dimen/dp_21"
android:layout_marginEnd="@dimen/dp_40"
android:background="@drawable/bg_tab_view_top"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<TextView
android:id="@+id/tv_report_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_reason"
android:textSize="@dimen/sp_40"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/view_title_bg"
app:layout_constraintBottom_toBottomOf="@id/view_title_bg"
app:layout_constraintStart_toStartOf="@id/view_title_bg"
android:layout_marginStart="@dimen/dp_32"
/>
<TextView
android:id="@+id/tv_work_order_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_open_time"
android:textColor="@color/white"
android:textSize="@dimen/sp_32"
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"
/>
<View
android:id="@+id/view_type_label"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="@drawable/bg_fault_reason_title_label"
app:layout_constraintTop_toBottomOf="@id/view_title_bg"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
/>
<TextView
android:id="@+id/tv_type_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/work_order_type"
android:textSize="@dimen/sp_32"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/view_type_label"
app:layout_constraintBottom_toBottomOf="@id/view_type_label"
app:layout_constraintLeft_toRightOf="@id/view_type_label"
android:layout_marginStart="@dimen/dp_13"
/>
<com.mogo.eagle.core.function.hmi.ui.widget.WrapRadioGroup
android:id="@+id/wrap_radio_group"
android:layout_width="@dimen/dp_779"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/view_type_label"
app:layout_constraintLeft_toLeftOf="@id/view_type_label"
android:layout_marginTop="@dimen/dp_18"
>
<RadioButton
android:id="@+id/rb_type_software"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_70"
android:text="@string/work_order_type_software"
style="@style/work_order_type_radio_style"
/>
<RadioButton
android:id="@+id/rb_type_kit"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_70"
android:text="@string/work_order_type_kit"
style="@style/work_order_type_radio_style"
android:layout_marginStart="@dimen/dp_33"
/>
<RadioButton
android:id="@+id/rb_type_vehicle"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_70"
android:text="@string/work_order_type_vehicle"
style="@style/work_order_type_radio_style"
android:layout_marginStart="@dimen/dp_33"
/>
<RadioButton
android:id="@+id/rb_type_capacity"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_70"
android:text="@string/work_order_type_capacity"
style="@style/work_order_type_radio_style"
android:layout_marginStart="@dimen/dp_33"
/>
<RadioButton
android:id="@+id/rb_type_environment"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_70"
android:text="@string/work_order_type_environment"
style="@style/work_order_type_radio_style"
android:layout_marginTop="@dimen/dp_35"
/>
<RadioButton
android:id="@+id/rb_type_other"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_70"
android:text="@string/work_order_type_other"
style="@style/work_order_type_radio_style"
android:layout_marginStart="@dimen/dp_33"
android:layout_marginTop="@dimen/dp_35"
/>
</com.mogo.eagle.core.function.hmi.ui.widget.WrapRadioGroup>
<View
android:id="@+id/view_time_label"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="@drawable/bg_fault_reason_title_label"
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"
/>
<TextView
android:id="@+id/tv_time_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/work_order_occurrence_time"
android:textColor="@color/white"
android:textSize="@dimen/sp_38"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/view_time_label"
app:layout_constraintBottom_toBottomOf="@id/view_time_label"
app:layout_constraintLeft_toRightOf="@id/view_time_label"
android:layout_marginStart="@dimen/dp_13"
/>
<View
android:id="@+id/view_time_bg"
android:layout_width="@dimen/dp_295"
android:layout_height="@dimen/dp_72"
app:layout_constraintLeft_toLeftOf="@id/view_time_label"
app:layout_constraintTop_toBottomOf="@id/tv_time_title"
android:layout_marginTop="@dimen/dp_15"
android:background="@drawable/bg_fault_type"
/>
<ImageView
android:id="@+id/iv_time_reduce"
android:layout_width="@dimen/dp_72"
android:layout_height="@dimen/dp_72"
android:src="@drawable/icon_fault_time_reduce"
app:layout_constraintTop_toTopOf="@id/view_time_bg"
app:layout_constraintBottom_toBottomOf="@id/view_time_bg"
app:layout_constraintLeft_toLeftOf="@id/view_time_bg"
android:contentDescription="@string/fault_time_reduce"
/>
<ImageView
android:id="@+id/iv_time_add"
android:layout_width="@dimen/dp_72"
android:layout_height="@dimen/dp_72"
android:src="@drawable/icon_fault_time_add"
app:layout_constraintTop_toTopOf="@id/view_time_bg"
app:layout_constraintBottom_toBottomOf="@id/view_time_bg"
app:layout_constraintRight_toRightOf="@id/view_time_bg"
android:contentDescription="@string/fault_time_add"
/>
<TextView
android:id="@+id/tv_occurrence_time"
android:layout_width="@dimen/dp_0"
android:layout_height="@dimen/dp_0"
android:textSize="@dimen/sp_30"
android:textColor="@color/white"
android:gravity="center"
android:background="#1AA7B6F0"
app:layout_constraintTop_toTopOf="@id/view_time_bg"
app:layout_constraintBottom_toBottomOf="@id/view_time_bg"
app:layout_constraintLeft_toRightOf="@id/iv_time_reduce"
app:layout_constraintRight_toLeftOf="@id/iv_time_add"
/>
<View
android:id="@+id/view_describe_label"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="@drawable/bg_fault_reason_title_label"
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"
/>
<TextView
android:id="@+id/tv_describe_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/work_order_describe"
android:textColor="@color/white"
android:textSize="@dimen/sp_38"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/view_describe_label"
app:layout_constraintBottom_toBottomOf="@id/view_describe_label"
app:layout_constraintStart_toEndOf="@id/view_describe_label"
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"
android:layout_height="@dimen/dp_115"
app:layout_constraintTop_toBottomOf="@id/view_describe_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:hint="@string/work_order_describe_input"
android:textColorHint="#A3ABC0"
android:textCursorDrawable="@drawable/work_order_input_cursor"
android:textSize="@dimen/sp_27"
android:textColor="@color/white"
android:gravity="top|start"
android:paddingStart="@dimen/dp_28"
android:paddingTop="@dimen/dp_21"
android:paddingEnd="@dimen/dp_80"
android:layout_marginTop="@dimen/dp_25"
android:background="@drawable/bg_fault_des_input"
/>
<ImageView
android:id="@+id/iv_describe_audio"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_59"
android:src="@drawable/icon_work_order_audio"
app:layout_constraintTop_toTopOf="@id/et_describe_input"
app:layout_constraintBottom_toBottomOf="@id/et_describe_input"
app:layout_constraintEnd_toEndOf="@id/et_describe_input"
android:layout_marginEnd="@dimen/dp_30"
android:contentDescription="@string/take_over_note_audio"
/>
<TextView
android:id="@+id/tv_work_order_report"
android:layout_width="@dimen/dp_380"
android:layout_height="@dimen/dp_80"
app:layout_constraintTop_toBottomOf="@id/et_describe_input"
app:layout_constraintLeft_toLeftOf="@id/et_describe_input"
android:background="@drawable/bg_fault_report"
android:text="@string/work_order_report"
android:textColor="#FFFFFF"
android:textSize="@dimen/sp_36"
android:textStyle="bold"
android:gravity="center"
android:layout_marginTop="@dimen/dp_97"
/>
<TextView
android:id="@+id/tv_work_order_cancel"
android:layout_width="@dimen/dp_380"
android:layout_height="@dimen/dp_80"
app:layout_constraintTop_toBottomOf="@id/et_describe_input"
app:layout_constraintRight_toRightOf="@id/et_describe_input"
android:text="@string/work_order_cancel"
android:textColor="#FFFFFF"
android:textSize="@dimen/sp_36"
android:textStyle="bold"
android:gravity="center"
android:background="@drawable/bg_fault_cancel"
android:layout_marginTop="@dimen/dp_97"
/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -206,4 +206,7 @@
<string name="fsm_icon">FSM图标</string>
<string name="v2x_icon">V2X图标</string>
<string name="fault_time_reduce">故障发生时间减少</string>
<string name="fault_time_add">故障发生时间增加</string>
</resources>