Merge remote-tracking branch 'origin/release_robotaxi-d-app-module_2120_221017_2.12.0.1'

# Conflicts:
#	core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainLauncherActivity.java
#	core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotProvider.kt
#	libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageType.java
This commit is contained in:
pangfan
2022-11-15 11:23:39 +08:00
287 changed files with 8616 additions and 3625 deletions

View File

@@ -35,8 +35,9 @@ class DevaToolsProvider : IDevaToolsProvider {
}
override fun initBiz() {
bizConfigCenter.init(mContext!!)
traceManager.init(mContext!!)
bizConfigCenter.init(mContext!!)
FuncConfigImpl.init()
MogoLogCatchManager.init(mContext!!)
}

View File

@@ -107,13 +107,24 @@ internal object BadCaseManager : LifecycleEventObserver {
if(ClickUtils.isFastClick()){
if(NetworkUtils.isConnected()){
if(BadCaseConfig.dockerVersion!=null){
val initiativeBadCaseWindow = InitiativeBadCaseWindow(activity)
initiativeBadCaseWindow.setClickListener(object: InitiativeBadCaseWindow.ClickListener{
override fun closeWindow() {
initiativeBadCaseWindow.hideFloatWindow()
}
})
initiativeBadCaseWindow.showFloatWindow()
//兼容老MAP版本
if(BadCaseConfig.dockerVersion!!.contains("2.3.0")
|| BadCaseConfig.dockerVersion!!.contains("2.4.0")
|| BadCaseConfig.dockerVersion!!.contains("2.5.0")
|| BadCaseConfig.dockerVersion!!.contains("2.6.0")
|| BadCaseConfig.dockerVersion!!.contains("2.8.0")){
val initiativeBadCaseWindow = InitiativeBadCaseWindow(activity)
initiativeBadCaseWindow.setClickListener(object: InitiativeBadCaseWindow.ClickListener{
override fun closeWindow() {
initiativeBadCaseWindow.hideFloatWindow()
}
})
initiativeBadCaseWindow.showFloatWindow(null)
}else{
val caseListDialog = CaseListDialog(activity)
caseListDialog.show()
}
}else{
ToastUtils.showShort("工控机连接状态异常")
}

View File

@@ -1,35 +1,37 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz
package com.zhjt.mogo_core_function_devatools.badcase.biz
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.RadioButton
import android.widget.RadioGroup
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.GridLayoutManager
import com.mogo.eagle.core.data.badcase.RecordTypeEntity
import com.mogo.eagle.core.data.badcase.TopicEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.utilcode.util.SizeUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.RecordTemplateAdapter
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import kotlinx.android.synthetic.main.layout_badcase_config.view.*
import mogo.telematics.pad.MessagePad
import java.lang.Exception
/**
/**
* @author XuXinChao
* @description BadCase上报信息配置页面
* @since: 2022/7/5
*/
internal class BadCaseConfigView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotRecordListener {
companion object {
@@ -37,18 +39,21 @@ defStyleAttr: Int = 0
}
private var clickListener: ClickListener? = null
private var recordTemplateAdapter: RecordTemplateAdapter? = null
private var mIdentity = BadCaseConfig.identity
private var mPreviousDuration = BadCaseConfig.previousDuration
private var mBackDuration = BadCaseConfig.backDuration
private var mType = 1
private var recordTypesList = ArrayList<RecordTypeEntity>()
private var caseTopicListDialog: CaseTopicListDialog? = null
init{
init {
LayoutInflater.from(context).inflate(R.layout.layout_badcase_config, this, true)
background = ColorDrawable(Color.parseColor("#F0151D41"))
initView()
}
private fun initView(){
private fun initView() {
//关闭BadCase配置窗口
ivConfigClose.setOnClickListener {
clickListener?.onClose()
@@ -75,41 +80,42 @@ defStyleAttr: Int = 0
//保存配置按钮
tvConfigSave.setOnClickListener {
//判断、保存录制时间信息
val preTimeStr=etInitiativePreTime.text.toString()
val afterTimeStr=etInitiativeAfterTime.text.toString()
val preTimeStr = etInitiativePreTime.text.toString()
val afterTimeStr = etInitiativeAfterTime.text.toString()
try {
if(preTimeStr.isEmpty()){
if (preTimeStr.isEmpty()) {
mPreviousDuration = BadCaseConfig.previousDuration
}else{
} else {
mPreviousDuration = preTimeStr.toInt()
}
if(afterTimeStr.isEmpty()){
if (afterTimeStr.isEmpty()) {
mBackDuration = BadCaseConfig.backDuration
}else{
} else {
mBackDuration = afterTimeStr.toInt()
}
if(mPreviousDuration<0 || mPreviousDuration>30){
if (mPreviousDuration < 0 || mPreviousDuration > 30) {
ToastUtils.showLong("前溯采集时长最长30S")
return@setOnClickListener
}
if(mBackDuration<0 || mBackDuration>300){
if (mBackDuration < 0 || mBackDuration > 300) {
ToastUtils.showLong("采集总时长最长300S")
return@setOnClickListener
}
if((mPreviousDuration+mBackDuration)<5){
if ((mPreviousDuration + mBackDuration) < 5) {
ToastUtils.showLong("采集总时长最短5S")
return@setOnClickListener
}
if((mPreviousDuration+mBackDuration)>300){
if ((mPreviousDuration + mBackDuration) > 300) {
ToastUtils.showLong("采集总时长最长300S")
return@setOnClickListener
}
BadCaseConfig.previousDuration = mPreviousDuration
BadCaseConfig.backDuration = mBackDuration
BadCaseConfig.totalDuration = BadCaseConfig.previousDuration + BadCaseConfig.backDuration
}catch (e: Exception){
BadCaseConfig.totalDuration =
BadCaseConfig.previousDuration + BadCaseConfig.backDuration
} catch (e: Exception) {
ToastUtils.showLong("输入时间格式不合法,请重新输入")
etInitiativePreTime.text = null
etInitiativeAfterTime.text = null
@@ -126,14 +132,14 @@ defStyleAttr: Int = 0
}
//现场恢复
when(BadCaseConfig.identity){
"安全员"->{
when (BadCaseConfig.identity) {
"安全员" -> {
rbSafetyOfficer.isChecked = true
}
"QA、研发"->{
"QA、研发" -> {
rbDeveloper.isChecked = true
}
"产品、运营、演示"->{
"产品、运营、演示" -> {
rbProduct.isChecked = true
}
}
@@ -141,128 +147,75 @@ defStyleAttr: Int = 0
etInitiativePreTime.hint = "${BadCaseConfig.previousDuration}S"
etInitiativeAfterTime.hint = "${BadCaseConfig.backDuration}S"
// val test1 = TestBean(1,"人工接管自动录制")
// val test2 = TestBean(2,"地图采集")
// val test3 = TestBean(3,"画龙问题排查")
// val test4 = TestBean(4,"误识别问题排查")
// val test5 = TestBean(5,"lidar+planning")
// val test6 = TestBean(6,"camera+planning")
// val test7 = TestBean(7,"bus lidar+planning")
// val test8 = TestBean(8,"bus camera+planning")
// val test99 = TestBean(99,"ai data")
//
// val list = ArrayList<TestBean>()
// list.add(test1)
// list.add(test2)
// list.add(test3)
// list.add(test4)
// list.add(test5)
// list.add(test6)
// list.add(test7)
// list.add(test8)
// list.add(test99)
// list.iterator().forEach {
// if(it.id!=99){
// val radioButton = RadioButton(context)
// val lp = RadioGroup.LayoutParams(
// RadioGroup.LayoutParams.WRAP_CONTENT,
// RadioGroup.LayoutParams.WRAP_CONTENT
// )
// //设置RadioButton边距 (int left, int top, int right, int bottom)
// lp.setMargins(
// SizeUtils.dp2px(0f),
// SizeUtils.dp2px(8f),
// SizeUtils.dp2px(10f),
// SizeUtils.dp2px(8f)
// )
// //设置RadioButton背景
// radioButton.setTextColor(Color.WHITE)
//
// radioButton.buttonDrawable = resources.getDrawable(R.drawable.badcase_radio_button_style)
// //设置文字距离四周的距离
// radioButton.setPadding(
// SizeUtils.dp2px(12f),
// SizeUtils.dp2px(5f),
// SizeUtils.dp2px(10f),
// SizeUtils.dp2px(5f)
// )
// radioButton.textSize = SizeUtils.sp2px(9f).toFloat()
// radioButton.id = it.id
// radioButton.isChecked = it.id == BadCaseConfig.type
// //设置文字
// radioButton.text = it.src
// //将radioButton添加到radioGroup中
// rgRecordConfig.addView(radioButton, lp)
// rgRecordConfig.setOnCheckedChangeListener { _, checkedId ->
// mType = checkedId
// }
// }
// }
recordTemplateAdapter = RecordTemplateAdapter()
recordTemplateAdapter?.setListener(object :RecordTemplateAdapter.ClickTemplateListener{
override fun onClick(recordTypeEntity: RecordTypeEntity) {
//弹窗Topic清单列表
showCaseTopicListDialog(recordTypeEntity)
}
})
val gridLayoutManager = GridLayoutManager(context,2)
rvTemplate.layoutManager = gridLayoutManager
rvTemplate.adapter = recordTemplateAdapter
rvTemplate.visibility = View.GONE
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
override fun onAutopilotRecordConfig(config: MessagePad.RecordDataConfig) {
super.onAutopilotRecordConfig(config)
ThreadUtils.runOnUiThread{
config.recordTypesList.iterator().forEach {
if(it.id!=99){
val radioButton = RadioButton(context)
val lp = RadioGroup.LayoutParams(
RadioGroup.LayoutParams.WRAP_CONTENT,
RadioGroup.LayoutParams.WRAP_CONTENT
)
//设置RadioButton边距 (int left, int top, int right, int bottom)
lp.setMargins(
SizeUtils.dp2px(0f),
SizeUtils.dp2px(8f),
SizeUtils.dp2px(10f),
SizeUtils.dp2px(8f)
)
//设置RadioButton背景
radioButton.setTextColor(Color.WHITE)
private fun showCaseTopicListDialog(recordTypeEntity: RecordTypeEntity){
caseTopicListDialog = CaseTopicListDialog(context)
caseTopicListDialog?.setData(recordTypeEntity)
caseTopicListDialog?.show()
}
radioButton.buttonDrawable = resources.getDrawable(R.drawable.badcase_radio_button_style)
//设置文字距离四周的距离
radioButton.setPadding(
SizeUtils.dp2px(12f),
SizeUtils.dp2px(5f),
SizeUtils.dp2px(10f),
SizeUtils.dp2px(5f)
)
radioButton.textSize = SizeUtils.sp2px(9f).toFloat()
radioButton.id = it.id
radioButton.isChecked = it.id == BadCaseConfig.type
//设置文字
radioButton.text = it.desc
//将radioButton添加到radioGroup中
rgRecordConfig.addView(radioButton, lp)
rgRecordConfig.setOnCheckedChangeListener { _, checkedId ->
mType = checkedId
}
}
}
}
}
override fun onAutopilotRecordConfig(config: MessagePad.RecordDataConfig) {
super.onAutopilotRecordConfig(config)
ThreadUtils.runOnUiThread {
if(BadCaseConfig.dockerVersion!!.contains("2.3.0")
|| BadCaseConfig.dockerVersion!!.contains("2.4.0")
|| BadCaseConfig.dockerVersion!!.contains("2.5.0")
|| BadCaseConfig.dockerVersion!!.contains("2.6.0")
|| BadCaseConfig.dockerVersion!!.contains("2.8.0")){
rvTemplate.visibility = View.GONE
}else{
config.recordTypesList.iterator().forEach {
if (it.id != 99){
val topicList = ArrayList<TopicEntity>()
it.topicsList.iterator().forEach {
topicList.add(TopicEntity(it,true,false))
}
recordTypesList.add(RecordTypeEntity(it.id,it.desc,topicList))
}
}
if(recordTypesList.size>1){
rvTemplate.visibility = View.VISIBLE
recordTemplateAdapter?.setData(recordTypesList)
recordTemplateAdapter?.notifyDataSetChanged()
}
}
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerAutopilotRecordListenerManager.addListener(TAG, this)
//获取数据采集录制模式配置列表
CallerAutoPilotManager.getBadCaseConfig()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerAutopilotRecordListenerManager.addListener(TAG, this)
//获取数据采集录制模式配置列表
CallerAutoPilotManager.getBadCaseConfig(0, 0, listOf())
recordTypesList.add(RecordTypeEntity(0,"自定义", arrayListOf()))
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutopilotRecordListenerManager.removeListener(TAG)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutopilotRecordListenerManager.removeListener(TAG)
recordTypesList.clear()
}
interface ClickListener{
fun onClose()
}
interface ClickListener {
fun onClose()
}
}

View File

@@ -0,0 +1,119 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.eagle.core.data.badcase.RecordCaseEntity;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import com.zhjt.mogo_core_function_devatools.R;
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.CaseListAdapter;
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig;
import java.util.ArrayList;
import mogo.telematics.pad.MessagePad;
import record_cache.RecordPanelOuterClass;
/**
* @author XuXinChao
* @description BadCase清单选择对话框
* @since: 2022/10/19
*/
public class CaseListDialog extends Dialog implements IMoGoAutopilotRecordListener {
private TextView tvCancel;
private RecyclerView rvCaseList;
private CaseListAdapter caseListAdapter;
private static final String TAG = "CaseListDialog";
private ArrayList<RecordCaseEntity> recordTypeEntityArrayList = new ArrayList<>();
private Activity activity;
public CaseListDialog(@NonNull Activity activity) {
super(activity, R.style.bad_case_dialog);
this.activity = activity;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_case_list);
setCanceledOnTouchOutside(false);
init();
initEvent();
}
private void init() {
tvCancel = findViewById(R.id.tvCancel);
rvCaseList = findViewById(R.id.rvCaseList);
caseListAdapter = new CaseListAdapter();
caseListAdapter.setListener(recordCaseEntity -> {
//录制Bag包弹窗
InitiativeBadCaseWindow initiativeBadCaseWindow = new InitiativeBadCaseWindow(activity);
initiativeBadCaseWindow.setClickListener(initiativeBadCaseWindow::hideFloatWindow);
initiativeBadCaseWindow.showFloatWindow(recordCaseEntity);
});
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(),2);
gridLayoutManager.setOrientation(RecyclerView.VERTICAL);
rvCaseList.setLayoutManager(gridLayoutManager);
rvCaseList.setAdapter(caseListAdapter);
}
private void initEvent() {
tvCancel.setOnClickListener(v -> dismiss());
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
CallerAutopilotRecordListenerManager.INSTANCE.addListener(TAG, this);
//获取数据采集录制模式配置列表
CallerAutoPilotManager.INSTANCE.getBadCaseConfig(0, 0,new ArrayList<>());
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
CallerAutopilotRecordListenerManager.INSTANCE.removeListener(TAG);
}
@Override
public void onAutopilotRecordResult(@NonNull RecordPanelOuterClass.RecordPanel recordPanel) {
}
@Override
public void onAutopilotRecordConfig(@NonNull MessagePad.RecordDataConfig config) {
ThreadUtils.runOnUiThread(() -> {
if(config.getRecordTypesCount()>0){
for(int index=0;index<config.getRecordTypesCount();index++){
if(config.getRecordTypes(index).getId() != 99){
ArrayList<String> topicList = new ArrayList<>();
// TODO java.lang.IndexOutOfBoundsException: Index: 38, Size: 38
// for(int position=0;index<config.getRecordTypes(index).getTopicsCount();position++){
// topicList.add(config.getRecordTypes(index).getTopicsList().get(position));
// }
recordTypeEntityArrayList.add(new RecordCaseEntity(
config.getRecordTypes(index).getId(),config.getRecordTypes(index).getDesc(),
topicList));
}
}
}
if(BadCaseConfig.customTopicList.size()>0){
recordTypeEntityArrayList.add(new RecordCaseEntity(0,"自定义A",BadCaseConfig.customTopicList));
}
caseListAdapter.setData(recordTypeEntityArrayList);
caseListAdapter.notifyDataSetChanged();
});
}
}

View File

@@ -0,0 +1,206 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.eagle.core.data.badcase.RecordTypeEntity;
import com.mogo.eagle.core.data.badcase.TopicEntity;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.zhjt.mogo_core_function_devatools.R;
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.TopicListAdapter;
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig;
import java.util.ArrayList;
import java.util.List;
import mogo.telematics.pad.MessagePad;
import record_cache.RecordPanelOuterClass;
/**
* @author XuXinChao
* @description BadCase Topic列表选择对话框
* @since: 2022/10/19
*/
public class CaseTopicListDialog extends Dialog implements IMoGoAutopilotRecordListener {
private static final String TAG = "CaseTopicListDialog";
private TextView tvCaseName;
private TextView tvSave;
private TextView tvCancel;
private ImageView ivSearch;
private EditText etSearch;
private RecyclerView rvTopicList;
private TopicListAdapter topicListAdapter;
private String searchStr;
private List<TopicEntity> allTopicList = new ArrayList<>();
private RecordTypeEntity recordType;
private List<String> addTopicList = new ArrayList<>();
private List<TopicEntity> searchTopicList = new ArrayList<>();
public CaseTopicListDialog(@NonNull Context context) {
super(context, R.style.bad_case_dialog);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_case_topic_list);
setCanceledOnTouchOutside(false);
CallerAutopilotRecordListenerManager.INSTANCE.addListener(TAG, this);
init();
initEvent();
//获取所有Topic
CallerAutoPilotManager.INSTANCE.getBadCaseConfig(1, 0, new ArrayList<>());
if(recordType!=null){
tvCaseName.setText(recordType.getDesc());
if(recordType.getTopicsList().size()>0){
topicListAdapter.setData(recordType.getTopicsList());
topicListAdapter.notifyDataSetChanged();
}
}
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
CallerAutopilotRecordListenerManager.INSTANCE.removeListener(TAG);
}
public void setData(RecordTypeEntity recordTypeEntity){
if(recordTypeEntity!=null){
recordType = recordTypeEntity;
}
}
private void init() {
tvCaseName = findViewById(R.id.tvCaseName);
tvSave = findViewById(R.id.tvSave);
tvCancel = findViewById(R.id.tvCancel);
ivSearch = findViewById(R.id.ivSearch);
etSearch = findViewById(R.id.etSearch);
rvTopicList = findViewById(R.id.rvTopicList);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rvTopicList.setLayoutManager(linearLayoutManager);
topicListAdapter = new TopicListAdapter();
topicListAdapter.setListener((topicName, clicked) -> {
if(clicked){
addTopicList.add(topicName);
}else{
addTopicList.remove(topicName);
}
});
rvTopicList.setAdapter(topicListAdapter);
}
private void initEvent() {
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
searchStr = s.toString();
if(searchStr!=null && searchStr.length()>0){
ivSearch.setImageDrawable(getContext().getDrawable(R.drawable.icon_bad_case_delect));
} else {
ivSearch.setImageDrawable(getContext().getDrawable(R.drawable.icon_bad_case_search));
}
if(searchStr!=null && searchStr.length()>0){
searchTopicList.clear();
for(int index=0;index<recordType.getTopicsList().size();index++){
if(recordType.getTopicsList().get(index).getTopicName().contains(searchStr)){
searchTopicList.add(recordType.getTopicsList().get(index));
}
}
topicListAdapter.setData(searchTopicList);
topicListAdapter.notifyDataSetChanged();
}
}
});
ivSearch.setOnClickListener(v -> {
if(searchStr!=null && searchStr.length()>0){
etSearch.setText("");
ivSearch.setImageDrawable(getContext().getDrawable(R.drawable.icon_bad_case_search));
topicListAdapter.setData(recordType.getTopicsList());
topicListAdapter.notifyDataSetChanged();
}
});
tvSave.setOnClickListener(v -> {
if(recordType!=null){
Boolean success=CallerAutoPilotManager.INSTANCE.getBadCaseConfig(2,recordType.getId(),addTopicList);
if(Boolean.TRUE.equals(success)){
ToastUtils.showShort("Topic设置成功");
if(recordType.getId() == 0){
//自定义Topic
BadCaseConfig.customTopicList.clear();
BadCaseConfig.customTopicList.addAll(addTopicList);
}
addTopicList.clear();
recordType.getTopicsList().removeAll(allTopicList);
dismiss();
}else{
ToastUtils.showShort("Topic设置失败");
}
}
});
tvCancel.setOnClickListener(v -> {
recordType.getTopicsList().removeAll(allTopicList);
dismiss();
});
}
@Override
public void onAutopilotRecordConfig(MessagePad.RecordDataConfig config) {
ThreadUtils.runOnUiThread(() -> {
Log.i("houyanli","AllTopicsCount="+config.getAllTopicsCount());
if(config.getAllTopicsCount()>0){
for(int index=0;index<config.getAllTopicsCount();index++){
if(!recordType.getTopicsList().contains(config.getAllTopics(index))){
allTopicList.add(new TopicEntity(config.getAllTopics(index),false,true));
}
Log.i("houyanli","topic="+config.getAllTopics(index));
}
recordType.getTopicsList().addAll(allTopicList);
topicListAdapter.setData(recordType.getTopicsList());
topicListAdapter.notifyDataSetChanged();
}
});
}
@Override
public void onAutopilotRecordResult(@NonNull RecordPanelOuterClass.RecordPanel recordPanel) {
}
}

View File

@@ -13,6 +13,7 @@ import android.widget.ImageView
import android.widget.TextView
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.badcase.RecordCaseEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarStateListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
@@ -137,13 +138,6 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
CallerAutopilotRecordListenerManager.addListener(this.hashCode().toString(),this)
// 添加 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.addListener(this.hashCode().toString(), this)
//开启录包
CallerAutoPilotManager.recordPackage(BadCaseConfig.type,
Random(SystemClock.elapsedRealtime()).nextInt(),
BadCaseConfig.totalDuration,
BadCaseConfig.previousDuration
)
viewAudioButton.setOnClickListener {
audioStatus = !audioStatus
setAudio(audioStatus)
@@ -337,7 +331,7 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
return true
}
fun showFloatWindow() {
fun showFloatWindow(recordCaseEntity: RecordCaseEntity?) {
if (mFloatLayout.parent == null) {
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
@@ -345,6 +339,14 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)-350
mWindowManager!!.addView(mFloatLayout, mWindowParams)
//开启录包
if(recordCaseEntity!=null){
CallerAutoPilotManager.recordPackage(recordCaseEntity.caseId,Random(SystemClock.elapsedRealtime()).nextInt(),
BadCaseConfig.totalDuration, BadCaseConfig.previousDuration,recordCaseEntity.topicList)
}else{
CallerAutoPilotManager.recordPackage(BadCaseConfig.type,Random(SystemClock.elapsedRealtime()).nextInt(),
BadCaseConfig.totalDuration, BadCaseConfig.previousDuration)
}
}
}

View File

@@ -0,0 +1,54 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.badcase.RecordCaseEntity
import com.zhjt.mogo_core_function_devatools.R
/**
* @author XuXinChao
* @description Case清单列表适配器
* @since: 2022/10/19
*/
class CaseListAdapter: RecyclerView.Adapter<CaseListAdapter.CaseListHolder>() {
private var data:List<RecordCaseEntity>? = null
private var caseClickListener: CaseClickListener?=null
fun setData( data: List<RecordCaseEntity>?){
this.data = data
}
fun setListener(listener: CaseClickListener){
caseClickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CaseListHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_case_list, parent, false)
return CaseListHolder(view)
}
override fun onBindViewHolder(holder: CaseListHolder, position: Int) {
data?.let {recordCaseEntity->
holder.caseName.text = recordCaseEntity[position].caseName
holder.caseName.setOnClickListener {
caseClickListener?.onClick(recordCaseEntity[position])
}
}
}
override fun getItemCount() = data?.size ?: 0
class CaseListHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var caseName: TextView = itemView.findViewById(R.id.caseName)
}
interface CaseClickListener{
fun onClick(recordCaseEntity: RecordCaseEntity)
}
}

View File

@@ -0,0 +1,55 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.badcase.RecordTypeEntity
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.biz.BadCaseConfigView
/**
* @author XuXinChao
* @description 录制模板清单列表适配器
* @since: 2022/10/19
*/
class RecordTemplateAdapter : RecyclerView.Adapter<RecordTemplateAdapter.RecordTemplateHolder>(){
private var data:List<RecordTypeEntity>? = null
private var clickTemplateListener: ClickTemplateListener? = null
fun setData( data: List<RecordTypeEntity>?){
this.data = data
}
fun setListener(listener: ClickTemplateListener){
clickTemplateListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecordTemplateHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_record_template, parent, false)
return RecordTemplateHolder(view)
}
override fun onBindViewHolder(holder: RecordTemplateHolder, position: Int) {
data?.let {recordTypeEntity->
holder.caseName.text = recordTypeEntity[position].desc
holder.caseName.setOnClickListener {
clickTemplateListener?.onClick(recordTypeEntity[position])
}
}
}
override fun getItemCount() = data?.size ?: 0
class RecordTemplateHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var caseName: TextView = itemView.findViewById(R.id.caseName)
}
interface ClickTemplateListener{
fun onClick(recordTypeEntity: RecordTypeEntity)
}
}

View File

@@ -0,0 +1,83 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.badcase.TopicEntity
import com.zhjt.mogo_core_function_devatools.R
/**
* @author XuXinChao
* @description Topic列表适配器
* @since: 2022/10/19
*/
class TopicListAdapter: RecyclerView.Adapter<TopicListAdapter.TopicListHolder>() {
private var data:MutableList<TopicEntity>? = null
private var topicClickListener: TopicClickListener? = null
fun setData( data: MutableList<TopicEntity>?){
this.data = data
}
fun setListener(listener: TopicClickListener){
topicClickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopicListHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_topic_list, parent, false)
return TopicListHolder(view)
}
override fun onBindViewHolder(holder: TopicListHolder, position: Int) {
data?.let{topicList->
holder.topic_check_box.text = topicList[position].topicName
holder.topic_check_box.setOnCheckedChangeListener(null)
holder.topic_check_box.isChecked = topicList[position].topicStatus
holder.topic_check_box.tag = topicList
holder.topic_check_box.isClickable = topicList[position].topicCanClick
holder.topic_check_box.setOnCheckedChangeListener { _, isChecked ->
topicList[position].topicStatus = isChecked
topicClickListener?.onClick(topicList[position].topicName,isChecked)
if(isChecked){
//滚动到置顶
moveItem(topicList[position],position,0)
}else{
var lastNotCan = 0 //最后一个不能选择的
for( i in 0 until itemCount){
var topicEntity = data?.get(i)
if (topicEntity != null) {
if(!topicEntity.topicCanClick){
lastNotCan = i
}
}
}
moveItem(topicList[position],position,lastNotCan)
}
}
}
}
private fun moveItem(topicEntity: TopicEntity,removePos: Int,insertedPos: Int){
data?.remove(topicEntity)
notifyItemRemoved(removePos)
notifyItemRangeChanged(removePos, itemCount - removePos)
data?.add(insertedPos, topicEntity)
notifyItemInserted(insertedPos)
notifyItemRangeChanged(insertedPos, itemCount)
}
override fun getItemCount() = data?.size ?: 0
class TopicListHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var topic_check_box: CheckBox = itemView.findViewById(R.id.topic_check_box);
}
interface TopicClickListener{
fun onClick(topicName: String,clicked: Boolean)
}
}

View File

@@ -27,7 +27,10 @@ object BadCaseConfig {
//工控机版本
@JvmField
var dockerVersion:String ?= null
@JvmField
var recordKeyList:ArrayList<Long> = ArrayList()
//自定义Topic清单列表
@JvmField
var customTopicList: ArrayList<String> = ArrayList()
}

View File

@@ -42,6 +42,11 @@ class FuncConfigCenter : IMogoOnMessageListener<FuncConfig>, IMoGoAutopilotCarCo
MogoAiCloudSocketManager.getInstance(AbsMogoApplication.getApp().applicationContext)
.registerOnMessageListener(FUNC_CONFIG_TYPE, this)
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
//未连接到工控,默认配置
val bizJson = SPUtils.getInstance("biz_config")
.getString("config", GsonUtils.toJson(defaultFuncConfig()))
refreshConfig(GsonUtils.fromJson(bizJson, FuncConfig::class.java))
}
override fun onAutopilotCarConfig(carConfigResp: MessagePad.CarConfigResp) {
@@ -49,14 +54,9 @@ class FuncConfigCenter : IMogoOnMessageListener<FuncConfig>, IMoGoAutopilotCarCo
UiThreadHandler.post {
funcConfigNetWorkModel.requestFuncConfig(carConfigResp.macAddress, {
SPUtils.getInstance("biz_config").put("config", GsonUtils.toJson(it))
refreshConfig(it)
}, {
val bizJson = SPUtils.getInstance("biz_config")
.getString("config", GsonUtils.toJson(defaultFuncConfig()))
refreshConfig(GsonUtils.fromJson(bizJson, FuncConfig::class.java))
})
refreshConfig(it) }, {})
}
}else{
} else {
ToastUtils.showLong("未获取到域控mac信息")
}
}
@@ -67,7 +67,7 @@ class FuncConfigCenter : IMogoOnMessageListener<FuncConfig>, IMoGoAutopilotCarCo
override fun onMsgReceived(obj: FuncConfig?) {
obj?.let {
refreshConfig(it)
invokeUpdate(it)
}
}
@@ -81,6 +81,10 @@ class FuncConfigCenter : IMogoOnMessageListener<FuncConfig>, IMoGoAutopilotCarCo
)
private fun refreshConfig(funcConfig: FuncConfig) {
BizManager.updateBizConfigData(funcConfig)
invokeUpdate(funcConfig)
}
private fun invokeUpdate(funcConfig: FuncConfig) {
funcConfig.business.forEach { business ->
CallerDevaToolsFuncConfigListenerManager.invokeDevaToolsFuncConfigBizUpdate(
business.biz.uppercase(),

View File

@@ -21,6 +21,7 @@ import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_LIMIT
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_LTA
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_OPT_LINE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_PNC_ACTIONS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_PNC_WARNING
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RAIN_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RTS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_SLW
@@ -90,6 +91,7 @@ class FuncConfigConst {
foundationSubList.add(SubBiz(BIZ_BYPASS, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_AUTOPILOT_LANE_SELECTION, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_PNC_ACTIONS, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_PNC_WARNING, lock = false, state = true, dependNode = "", data = ""))
businessList.add(Business(FOUNDATION,foundationSubList))
return FuncConfig(0, AppUtils.getAppVersionCode(), getChannelCode(), getEnv(), businessList)

View File

@@ -2,6 +2,7 @@ package com.zhjt.mogo_core_function_devatools.funcconfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_BEAUTY_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_PNC_WARNING
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RAIN_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_WARNING_UPLOAD
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.FOUNDATION
@@ -14,7 +15,7 @@ object FuncConfigImpl {
fun init() {
CallerDevaToolsFuncConfigListenerManager.registerDevaToolsFuncConfigListener(FOUNDATION,
TAG,
TAG,false,
object : IMoGoDevaToolsFuncConfigListener {
override fun updateBizData(
type: String,
@@ -23,7 +24,11 @@ object FuncConfigImpl {
data: String?
) {
when (type) {
}
BIZ_BEAUTY_MODE -> FunctionBuildConfig.isDemoMode = state
BIZ_RAIN_MODE -> FunctionBuildConfig.isRainMode = state
BIZ_WARNING_UPLOAD -> FunctionBuildConfig.isReportWarning = state
BIZ_PNC_WARNING -> FunctionBuildConfig.isPNCWarning = state
}
}
}
)

View File

@@ -34,8 +34,9 @@ class FuncConfigNetWorkModel {
if (error == null) {
error = onError
}
//todo test
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["mac"] = mac
map["mac"] = DeviceUtils.getMacAddress()
map["channelVersion"] = FuncConfigConst.getChannelCode()
}
loader {

View File

@@ -42,51 +42,51 @@ object StatusManager {
private const val TAG = "StatusManager"
private lateinit var model: StatusModel
private var timer: Job? = null
// private var timer: Job? = null
private var hasInit = false
private val listeners by lazy { CopyOnWriteArrayList<IStatusListener>() }
private var container: WeakReference<ViewGroup>? = null
private val listener = object : IMoGoAutopilotStatusListener {
override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
super.onAutopilotGuardian(guardianInfo)
guardianInfo?.code?.takeIf {
CallerLogger.d("$M_DEVA$TAG", "-- onAutopilotGuardian ---: code: $it")
it.contains("RTK_STATUS", true) || it.contains("CAN", true) || it == "ILCT_RTK_OR_SLAM_CHANGE"
}?.run {
CallerLogger.d("$M_DEVA$TAG", "-- onAutopilotGuardian trigger req ---: code: $this")
req()
}
}
}
// private val listener = object : IMoGoAutopilotStatusListener {
// override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
// super.onAutopilotGuardian(guardianInfo)
// guardianInfo?.code?.takeIf {
// CallerLogger.d("$M_DEVA$TAG", "-- onAutopilotGuardian ---: code: $it")
// it.contains("RTK_STATUS", true) || it.contains("CAN", true) || it == "ILCT_RTK_OR_SLAM_CHANGE"
// }?.run {
// CallerLogger.d("$M_DEVA$TAG", "-- onAutopilotGuardian trigger req ---: code: $this")
// req()
// }
// }
// }
private val appStateListener = object : IAppStateListener {
override fun onAppStateChanged(isForeground: Boolean) {
if (isForeground) {
req()
} else {
timer?.cancel()
}
}
}
// private val appStateListener = object : IAppStateListener {
//
// override fun onAppStateChanged(isForeground: Boolean) {
// if (isForeground) {
// req()
// } else {
// timer?.cancel()
// }
// }
// }
private val flows: ArrayList<IFlow<out Status>> by lazy {
ArrayList()
}
private fun req() {
timer?.cancel()
model.viewModelScope.launch(Dispatchers.IO) {
CallerAutoPilotManager.sendStatusQueryReq()
while (true) {
delay(60000) //一分钟主动请求一次
CallerAutoPilotManager.sendStatusQueryReq()
}
}.also {
timer = it
}
}
// private fun req() {
// timer?.cancel()
// model.viewModelScope.launch(Dispatchers.IO) {
// CallerAutoPilotManager.sendStatusQueryReq()
// while (true) {
// delay(60000) //一分钟主动请求一次
// CallerAutoPilotManager.sendStatusQueryReq()
// }
// }.also {
// timer = it
// }
// }
fun init(ctx: Context) {
if (hasInit) {
@@ -109,9 +109,9 @@ object StatusManager {
private fun onCreate(ctx: Context) {
val values = model.status.value?.second ?: throw IllegalStateException("state is not right.")
CallerAutoPilotStatusListenerManager.addListener(TAG, listener)
AppStateManager.registerAppStateListener(appStateListener)
req()
// CallerAutoPilotStatusListenerManager.addListener(TAG, listener)
// AppStateManager.registerAppStateListener(appStateListener)
// req()
values.map {
when (it) {
is CanStatus -> CanImpl(ctx)
@@ -166,9 +166,9 @@ object StatusManager {
private fun onDestroy(ctx: Context) {
hasInit = false
CallerAutoPilotStatusListenerManager.removeListener(TAG)
AppStateManager.unRegisterAppStateListener(appStateListener)
timer?.cancel()
// CallerAutoPilotStatusListenerManager.removeListener(TAG)
// AppStateManager.unRegisterAppStateListener(appStateListener)
// timer?.cancel()
flows.forEach {
it.onDestroy()
}

View File

@@ -32,9 +32,9 @@ internal class TracingImpl(ctx: Context): IFlow<TracingStatus>(ctx), IMoGoAutopi
super.onAutopilotGuardian(guardianInfo)
val current = guardianInfo?.code
val newState = current?.toState(guardianInfo.msg)
if (newState != null && newState != old) {
send(TracingStatus(newState))
if (newState != null) {
old = newState
send(TracingStatus(newState))
}
}

View File

@@ -129,14 +129,14 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
MAP_TRA_TYPE -> {
"暂无轨迹"
}
MAP_DATA_EXIST -> "地图数据存在,正在加载${if (extraDesc.isEmpty()) "" else "[$extraDesc]" }"
MAP_DATA_NOT_EXIST -> "地图数据不存在${if (extraDesc.isEmpty()) "" else "[$extraDesc]"}"
TRACK_FINDED -> "轨迹类型:循迹[已找到轨迹$extraDesc]"
TRACK_LOADED -> "轨迹类型:循迹[加载成功$extraDesc]"
TRACK_NOT_EXIST -> "轨迹类型:循迹[不存在$extraDesc]"
TRACK_LOAD_FAIL -> "轨迹类型:循迹[加载失败$extraDesc]"
ROUTE_LOADED -> "轨迹类型:自主算路[加载成功$extraDesc]"
ROUTE_FAILED -> "轨迹类型:自主算路[加载失败$extraDesc]"
MAP_DATA_EXIST -> "地图数据存在,正在加载${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
MAP_DATA_NOT_EXIST -> "地图数据不存在${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_FINDED -> "轨迹类型:循迹(已找到轨迹)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_LOADED -> "轨迹类型:循迹(加载成功)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_NOT_EXIST -> "轨迹类型:循迹(未找到轨迹)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_LOAD_FAIL -> "轨迹类型:循迹(加载失败)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
ROUTE_LOADED -> "轨迹类型:自主算路(加载成功)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
ROUTE_FAILED -> "轨迹类型:自主算路(加载失败)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
UNKNOWN -> "暂无轨迹"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#3B4577" />
<corners android:radius="32px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#29305E" />
<corners android:radius="48px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#29305E" />
<corners android:radius="20px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#2B6EFF" />
<corners android:radius="20px" />
</shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/case_list_select" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="@drawable/case_list_select" android:state_focused="false" android:state_pressed="true" />
<item android:drawable="@drawable/case_list_select" android:state_selected="true" />
<item android:drawable="@drawable/case_list_select" android:state_focused="true" />
<item android:drawable="@drawable/case_list_normal" />
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#33E1E5FF" />
<corners android:radius="32px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#29305E" />
<corners android:radius="32px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#3B4577" />
<corners android:radius="24px" />
</shape>

View File

@@ -0,0 +1,61 @@
<?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="1110px"
android:layout_height="668px"
android:background="#3B4577"
app:roundLayoutRadius="32px"
>
<TextView
android:id="@+id/tvCaseListTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="case清单"
android:textColor="#FFFFFFFF"
android:textSize="56px"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="50px"
/>
<TextView
android:id="@+id/tvCancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消"
android:textColor="#FFFFFFFF"
android:textSize="52px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:paddingBottom="50px"
android:gravity="center"
/>
<View
android:id="@+id/viewCancelDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#66B8BFE8"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvCancel"
android:layout_marginBottom="50px"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvCaseList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCaseListTitle"
app:layout_constraintBottom_toTopOf="@id/viewCancelDivider"
android:layout_margin="50px"
/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="1270px"
android:layout_height="959px"
>
<TextView
android:id="@+id/tvCaseName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="56px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="50px"
/>
<View
android:id="@+id/viewVerticalLine"
android:layout_width="2px"
android:layout_height="160px"
android:background="#66B8BFE8"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<View
android:id="@+id/viewHorizontalLine"
android:layout_width="match_parent"
android:layout_height="2px"
android:background="#66B8BFE8"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/viewVerticalLine"
/>
<TextView
android:id="@+id/tvSave"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/viewHorizontalLine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/viewVerticalLine"
android:text="保存"
android:textColor="#FFFFFFFF"
android:textSize="52px"
android:gravity="center"
/>
<TextView
android:id="@+id/tvCancel"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/viewHorizontalLine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/viewVerticalLine"
app:layout_constraintRight_toRightOf="parent"
android:text="取消"
android:textColor="#FFFFFFFF"
android:textSize="52px"
android:gravity="center"
/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clSearchLayout"
android:layout_width="1030px"
android:layout_height="96px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCaseName"
android:layout_marginTop="50px"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="@drawable/bad_case_search_bg"
>
<ImageView
android:id="@+id/ivSearch"
android:layout_width="38px"
android:layout_height="42px"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:src="@drawable/icon_bad_case_search"
android:layout_marginEnd="40px"
/>
<EditText
android:id="@+id/etSearch"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/ivSearch"
android:hint="topic搜索"
android:textSize="38px"
android:textColor="#FFFFFFFF"
android:textColorHint="#B3FFFFFF"
android:background="@null"
android:layout_marginStart="40px"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTopicList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="@id/clSearchLayout"
app:layout_constraintRight_toRightOf="@id/clSearchLayout"
app:layout_constraintTop_toBottomOf="@id/clSearchLayout"
app:layout_constraintBottom_toTopOf="@id/viewHorizontalLine"
android:layout_marginTop="50px"
android:layout_marginBottom="20dp"
android:scrollbars="vertical"
android:fadeScrollbars="false"
style="@style/rv_vertical_style"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/caseName"
android:layout_width="match_parent"
android:layout_height="116px"
android:textColor="#FFFFFFFF"
android:textSize="43px"
android:background="@drawable/case_list_selector"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:clickable="true"
android:focusable="true"
>
</TextView>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/caseName"
android:layout_width="match_parent"
android:layout_height="84px"
android:textColor="#FFFFFFFF"
android:textSize="34px"
android:background="@drawable/case_list_selector"
android:gravity="center"
android:layout_marginTop="20dp"
android:clickable="true"
android:focusable="true"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
>
</TextView>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topic_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@drawable/badcase_radio_button_style"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:textColor="#FFFFFFFF"
android:textSize="38px"
android:paddingStart="5dp"
android:gravity="center_vertical"
>
</CheckBox>

View File

@@ -308,15 +308,18 @@
android:layout_marginStart="@dimen/dp_30"
/>
<RadioGroup
android:id="@+id/rgRecordConfig"
android:layout_width="0dp"
android:layout_height="match_parent"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTemplate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="@id/tvRecordTemplate"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvRecordTemplate"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="@dimen/dp_20"
android:background="@drawable/template_list_bg"
android:layout_marginTop="@dimen/dp_50"
android:layout_marginBottom="@dimen/dp_50"
android:paddingBottom="10dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="bad_case_dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@drawable/bad_case_dialog_bg</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="rv_vertical_style">
<item name="android:scrollbarSize">5dp</item>
<item name="android:scrollbars">horizontal</item>
<item name="android:scrollbarThumbVertical">@drawable/rv_scroll_bar_thumb</item>
<item name="android:scrollbarTrackVertical">@drawable/rv_scroll_bar_track</item>
</style>
</resources>