diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/fragment/BaseSweeperTabFragment.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/fragment/BaseSweeperTabFragment.java index 1837741692..a92ebe344d 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/fragment/BaseSweeperTabFragment.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/fragment/BaseSweeperTabFragment.java @@ -59,10 +59,6 @@ public abstract class BaseSweeperTabFragment {//跳过任务 + when (itemType.code) { + TaskStatusEnum.JUMP_OVER_SUBTASK.code -> {//跳过任务 presenter?.subTaskSkip(mSubTaskId, mIsLastSubTask) //mock - if (mSubTaskType == SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE){//人工驾驶子任务 + if (mSubTaskType.code == SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE.code){//人工驾驶子任务 showAmapNaviToStationFragment(false) } mCurrentSubPosition++ - currentTaskPanelView.setData(workModePanelView, mSubTaskBean, mCurrentSubPosition, this@SweeperFragment, presenter) + sweeper_current_task_view.setData(sweeper_cl_work_mode, mSubTaskBean, mCurrentSubPosition, this@SweeperFragment, presenter) } - TaskStatusEnum.END_TASK -> { + TaskStatusEnum.END_TASK.code -> { subTaskEnd() } } @@ -172,7 +190,7 @@ class SweeperFragment : BaseSweeperTabFragment?) { setShowCurrentTaskPanelView(false) setShowTaskListPanelView(true) - workModePanelView.visibility = View.GONE + sweeper_cl_work_mode.visibility = View.GONE if (mainTaskBeanList != null && mainTaskBeanList.isNotEmpty()) { noTaskDataView.visibility = View.GONE sweeperListCl.visibility = View.VISIBLE @@ -199,13 +217,13 @@ class SweeperFragment : BaseSweeperTabFragment {//子任务结束 + when (typeEnum.code) { + TaskStatusEnum.END_SUBTASK.code -> {//子任务结束 mCurrentSubPosition++ setSubTaskData() presenter?.getSubTaskDetail(mSubTaskId, mSubTaskType) - if (mSubTaskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE) {//自动驾驶子任务 + if (mSubTaskType.code == SubTaskTypeEnum.AUTOPILOT_SUBTYPE.code) {//自动驾驶子任务 presenter?.startTask(mSubTaskId, mSubTaskType) } } - TaskStatusEnum.JUMP_OVER_SUBTASK -> { //子任务跳过 + TaskStatusEnum.JUMP_OVER_SUBTASK.code -> { //子任务跳过 presenter?.subTaskEnd(mSubTaskId, mIsLastSubTask) - if (mSubTaskType == SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE){//人工驾驶子任务 + if (mSubTaskType.code == SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE.code){//人工驾驶子任务 showAmapNaviToStationFragment(false) } } - TaskStatusEnum.START_SUBTASK -> { //子任务开始 - if (mSubTaskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE) {//自动驾驶子任务 - readyTaskBtn("暂停任务", true, true) + TaskStatusEnum.START_SUBTASK.code -> { //子任务开始 + if (mSubTaskType.code == SubTaskTypeEnum.AUTOPILOT_SUBTYPE.code) {//自动驾驶子任务 + readyTaskBtn(true, true) }else{ - readyTaskBtn("准备出发", false, false) + readyTaskBtn(false, false) } setShowTaskListPanelView(false) - workModePanelView.visibility = View.VISIBLE + sweeper_cl_work_mode.visibility = View.VISIBLE setShowCurrentTaskPanelView(true) - currentTaskPanelView.setCurrentData(mCurrentSubPosition) - workModePanelView.setSweeperFutianCleanSystemState( - mSubTaskType, - if (mCleanSystemState == null) SweeperFutianCmdUtil.buildSweeperFuTionCleanSystemStateMockData() else mCleanSystemState, - trafficDataView - ) + sweeper_current_task_view.setCurrentData(mCurrentSubPosition) +// sweeper_cl_work_mode.setSweeperFutianCleanSystemState( +// mSubTaskType, +// if (mCleanSystemState == null) SweeperFutianCmdUtil.buildSweeperFuTionCleanSystemStateMockData() else mCleanSystemState +// ) } } @@ -260,7 +277,7 @@ class SweeperFragment : BaseSweeperTabFragment private int mSubTaskId = 0; //当前是否最后一个子任务 private boolean mIsLastSubtask = false; + // 底盘数据回调时间间隔 + private static final long VEHICLE_STATE_INTERVAL_MILLIS = 500L; + // 当前时间戳 + private long mCurrentTimeMillis; public SweeperPresenter(SweeperFragment view) { super(view); @@ -95,9 +103,10 @@ public class SweeperPresenter extends Presenter @Override public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autopilotStatusInfo) { if (autopilotStatusInfo == null) return; + CallerLogger.INSTANCE.d(M_SWEEPER + TAG,"onAutopilotStatusResponse sate:"+autopilotStatusInfo.getState()); switch (autopilotStatusInfo.getState()) { case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE://不可自动驾驶 - runOnUIThread(() -> mView.readyTaskBtn("准备出发", false, false)); + runOnUIThread(() -> mView.readyTaskBtn(false, false)); break; case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE://人工驾驶 if (SweeperTaskModel.getInstance().getSubWorking()) { @@ -110,16 +119,16 @@ public class SweeperPresenter extends Presenter SweeperTaskModel.getInstance().closeBeautificationMode(); } } - runOnUIThread(() -> mView.readyTaskBtn("准备出发", true, false)); + runOnUIThread(() -> mView.readyTaskBtn(true, false)); break; case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING://自动驾驶中 if (SweeperTaskModel.getInstance().getSubWorking()) { if (FunctionBuildConfig.isDemoMode) {//美化模式开启时 SweeperTaskModel.getInstance().startBeautificationMode(); } - runOnUIThread(() -> mView.readyTaskBtn("暂停任务", true, true)); + runOnUIThread(() -> mView.readyTaskBtn( true, true)); } else { - runOnUIThread(() -> mView.readyTaskBtn("准备出发", true, false)); + runOnUIThread(() -> mView.readyTaskBtn(true, false)); } case IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING://平行驾驶 if (SweeperTaskModel.getInstance().getSubWorking()) { @@ -133,7 +142,7 @@ public class SweeperPresenter extends Presenter SweeperTaskModel.getInstance().closeBeautificationMode(); } } - runOnUIThread(() -> mView.readyTaskBtn("准备出发", true, false)); + runOnUIThread(() -> mView.readyTaskBtn(true, false)); break; default: break; @@ -221,6 +230,57 @@ public class SweeperPresenter extends Presenter @Override public void onSweeperFutianCleanSystemState(@NonNull ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) { + long current = System.currentTimeMillis(); + if (current - mCurrentTimeMillis <= VEHICLE_STATE_INTERVAL_MILLIS) { + return; + } + mCurrentTimeMillis = current; + boolean clean_open_requirement = cleanSystemState.getSecuMotWorkSts(); + // 洗扫 + boolean clean_mode_wash_sweep = cleanSystemState.getSecuModWashSweepSts(); + // 纯洗 + boolean clean_mode_pure_wash = cleanSystemState.getSecuModWashSts(); + // 纯吸 + boolean clean_mode_pure_draw = cleanSystemState.getSecuWorkTonSts(); + // 左侧 + boolean clean_direction_left_side = cleanSystemState.getSecuWorkLeftSts(); + // 右侧 + boolean clean_direction_right_side = cleanSystemState.getSecuWorkRightSts(); + // 两侧 + boolean clean_direction_both_side = cleanSystemState.getSecuWorkOnBothsidesSts(); + // 作业强度状态 + boolean clean_intensity_standard = cleanSystemState.getSecuWorkStandSts(); + boolean clean_intensity_strong = cleanSystemState.getSecuWorkStrongSts(); + + // 纯扫 模式判断:不是另外其他3个模式,同时有清扫方向,说明开启了纯扫模式 + boolean clean_mode_pure_sweep = SweeperFutianCmdUtil.checkIfCleanModePureSweep(cleanSystemState); + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("开关:") + .append(clean_open_requirement) + .append("\n") + .append("纯扫:") + .append(clean_mode_wash_sweep) + .append("纯洗:") + .append(clean_mode_pure_wash) + .append("纯吸:") + .append(clean_mode_pure_draw) + .append("纯扫:") + .append("\n") + .append(clean_mode_pure_sweep) + .append("左侧:") + .append(clean_direction_left_side) + .append("右侧:") + .append(clean_direction_right_side) + .append("两侧:") + .append("\n") + .append(clean_direction_both_side) + .append("标准:") + .append(clean_intensity_standard) + .append("强力:") + .append(clean_intensity_strong); + + CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onSweeperFutianCleanSystemState:"+stringBuilder); runOnUIThread(() -> mView.onSweeperFutianCleanSystemState(cleanSystemState)); } @@ -257,10 +317,8 @@ public class SweeperPresenter extends Presenter */ public void startTask(int subTaskId, SubTaskTypeEnum subTaskType) { if (SweeperTaskModel.getInstance().getSubWorking()) {//如果任务正在执行中,被人工接管后掉出自驾,则只重启自动驾驶 - if (subTaskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE){ + if (subTaskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE) { SweeperTaskModel.getInstance().startAutopilot(); - }else{ - } } else { SweeperTaskModel.getInstance().subTaskStart(subTaskId, subTaskType); @@ -324,8 +382,8 @@ public class SweeperPresenter extends Presenter } @Override - public void setSubTaskBean(SweeperSubTaskBean subTaskBean,boolean isWorkingSubTask) { - mView.setSubTaskBean(subTaskBean,isWorkingSubTask); + public void setSubTaskBean(SweeperSubTaskBean subTaskBean, boolean isWorkingSubTask) { + mView.setSubTaskBean(subTaskBean, isWorkingSubTask); } @Override diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/SweeperOperatePanelView.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/SweeperOperatePanelView.java index cad2cc733e..e8620e25f9 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/SweeperOperatePanelView.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/SweeperOperatePanelView.java @@ -10,6 +10,7 @@ import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_PURE_SWE import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_PURE_WASH; import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_WASH_SWEEP; +import android.animation.ObjectAnimator; import android.content.Context; import android.os.Handler; import android.os.Message; @@ -17,7 +18,10 @@ import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; +import android.view.animation.LinearInterpolator; import android.widget.CheckedTextView; +import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -32,6 +36,7 @@ import com.mogo.och.sweeper.R; import com.mogo.och.sweeper.callback.CleaningModeStateCallback; import com.mogo.och.sweeper.constant.OperateStateEnum; import com.mogo.och.sweeper.util.SweeperFutianCmdUtil; +import com.mogo.och.sweeper.view.NoTouchConstraintLayout; import java.util.Arrays; import java.util.HashMap; @@ -42,6 +47,8 @@ import chassis.SpecialVehicleTaskCmdOuterClass; import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_DIRECTION_CLOSE; import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_CLOSE; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_WORK_CLOSE; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_WORK_OPEN; /** * 清扫车操作面板View @@ -51,6 +58,7 @@ public class SweeperOperatePanelView extends LinearLayout { private static final String TAG = "SweeperOperatePanelView"; private static final int CMD_EXECUTE_TIMEOUT_SECONDS = 30; private static final int CMD_EXECUTE_MOCK_SUCCESS_SECONDS = 3; + private boolean isFirst = false; CheckedTextView mBtnCleanWorkOpenClose;//开关 CheckedTextView mBtnCleanModePureSweep;//纯扫 @@ -62,9 +70,10 @@ public class SweeperOperatePanelView extends LinearLayout { CheckedTextView mBtnCleanDirectionBothSide;//两侧 CheckedTextView mBtnCleanIntensityStandard;//普通 CheckedTextView mBtnCleanIntensityStrong;//强力 - LinearLayout mLoadingContainer;//loading container - TextView mLoadingHintTop;//loading 提示-上面 - TextView mLoadingHintBottom;//loading 提示-下面 + FrameLayout mLoadingContainer;//loading container + TextView mLoadingHint;//loading 文本提示 + ImageView mLoadingView;//loading 转圈动画 + NoTouchConstraintLayout mWorkmodePanelRootView; // 作业模式相关操作按钮的id List cleanModeBtnViewIds = Arrays.asList( @@ -114,6 +123,10 @@ public class SweeperOperatePanelView extends LinearLayout { private CleaningModeStateCallback cleaningModeStateCallback; + private OperateStateEnum operateStateEnum = OperateStateEnum.SYNCING_STATUS; + + private ObjectAnimator objectAnimator; + private static ChassisStatesOuterClass.SweeperFuTianTaskSystemStates mCurrentCleanSystemState;//当前作业模式 public SweeperOperatePanelView(Context context) { @@ -138,6 +151,7 @@ public class SweeperOperatePanelView extends LinearLayout { private void initView(Context context) { LayoutInflater.from(context).inflate(R.layout.sweeper_operate_panel_view, this, true); mBtnCleanWorkOpenClose = (CheckedTextView) findViewById(R.id.btn_clean_work_open_close); + mWorkmodePanelRootView = (NoTouchConstraintLayout) findViewById(R.id.work_mode_panel_root_view); mBtnCleanModePureSweep = (CheckedTextView) findViewById(R.id.btn_clean_mode_pure_sweep); mBtnCleanModePureWash = (CheckedTextView) findViewById(R.id.btn_clean_mode_pure_wash); mBtnCleanModeSweepWash = (CheckedTextView) findViewById(R.id.btn_clean_mode_sweep_wash); @@ -148,8 +162,8 @@ public class SweeperOperatePanelView extends LinearLayout { mBtnCleanIntensityStandard = (CheckedTextView) findViewById(R.id.btn_clean_intensity_standard); mBtnCleanIntensityStrong = (CheckedTextView) findViewById(R.id.btn_clean_intensity_strong); mLoadingContainer = findViewById(R.id.loading_hint_container); - mLoadingHintTop = findViewById(R.id.loading_hint_top); - mLoadingHintBottom = findViewById(R.id.loading_hint_bottom); + mLoadingHint = findViewById(R.id.loading_hint); + mLoadingView = findViewById(R.id.loading_view); initViewListener(); } @@ -165,6 +179,7 @@ public class SweeperOperatePanelView extends LinearLayout { setClickListener(mBtnCleanIntensityStandard, (v) -> onCleanIntensityBtnClick(v)); setClickListener(mBtnCleanIntensityStrong, (v) -> onCleanIntensityBtnClick(v)); } + /** * 清扫任务开关按钮点击事件 */ @@ -198,21 +213,19 @@ public class SweeperOperatePanelView extends LinearLayout { @Override public void onCmdSuccess() { - runOnUIThread(() -> { - if (isCloseAction) { - mBtnCleanWorkOpenClose.setText("打开"); - mBtnCleanWorkOpenClose.setChecked(false); - toggleCleanModeBtnsStatus(false); - toggleCleanDirectionBtnsStatus(false); - toggleCleanIntensityBtnsStatus(false); - } else { - mBtnCleanWorkOpenClose.setText("关闭"); - mBtnCleanWorkOpenClose.setChecked(true); - toggleCleanModeBtnsStatus(true); - } - hideLoadingMask(); - showCmdExecuteSuccessToast(); - }); + if (isCloseAction) { + mBtnCleanWorkOpenClose.setText("打开"); + mBtnCleanWorkOpenClose.setChecked(false); + toggleCleanModeBtnsStatus(false); + toggleCleanDirectionBtnsStatus(false); + toggleCleanIntensityBtnsStatus(false); + } else { + mBtnCleanWorkOpenClose.setText("关闭"); + mBtnCleanWorkOpenClose.setChecked(true); + toggleCleanModeBtnsStatus(true); + } + hideLoadingMask(); + showCmdExecuteSuccessToast(); } @Override @@ -222,17 +235,15 @@ public class SweeperOperatePanelView extends LinearLayout { @Override public void onCmdTimeout() { //按钮样式恢复原样 - runOnUIThread(() -> { - if (isCloseAction) { - mBtnCleanWorkOpenClose.setText("打开"); - mBtnCleanWorkOpenClose.setChecked(true); - } else { - mBtnCleanWorkOpenClose.setText("关闭"); - mBtnCleanWorkOpenClose.setChecked(false); - } - hideLoadingMask(); - showCmdExecuteTimeoutToast(); - }); + if (isCloseAction) { + mBtnCleanWorkOpenClose.setText("关闭"); + mBtnCleanWorkOpenClose.setChecked(true); + } else { + mBtnCleanWorkOpenClose.setText("打开"); + mBtnCleanWorkOpenClose.setChecked(false); + } + hideLoadingMask(); + showCmdExecuteTimeoutToast(); } }; if (isCloseAction) { @@ -328,25 +339,23 @@ public class SweeperOperatePanelView extends LinearLayout { @Override public void onCmdSuccess() { - runOnUIThread(() -> { - ((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedModeBtn); - toggleCleanModeBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedModeBtn); - if (isClickCurrentChoosedModeBtn) { + ((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedModeBtn); + toggleCleanModeBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedModeBtn); + if (isClickCurrentChoosedModeBtn) { + toggleCleanDirectionBtnsStatus(false); + toggleCleanIntensityBtnsStatus(false); + } else { + // 如果是纯吸,没有设置清扫方向,同时自动设置作业强度为标准 + if (isPureAbsorptionClick) { toggleCleanDirectionBtnsStatus(false); - toggleCleanIntensityBtnsStatus(false); + setCleanIntensityStandard(); } else { - // 如果是纯吸,没有设置清扫方向,同时自动设置作业强度为标准 - if (isPureAbsorptionClick) { - toggleCleanDirectionBtnsStatus(false); - setCleanIntensityStandard(); - } else { - toggleCleanDirectionBtnsStatus(true); - toggleCleanIntensityBtnsStatus(false); - } + toggleCleanDirectionBtnsStatus(true); + toggleCleanIntensityBtnsStatus(false); } - hideLoadingMask(); - showCmdExecuteSuccessToast(); - }); + } + hideLoadingMask(); + showCmdExecuteSuccessToast(); } @Override @@ -355,11 +364,9 @@ public class SweeperOperatePanelView extends LinearLayout { @Override public void onCmdTimeout() { - runOnUIThread(() -> { - ((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedModeBtn); - hideLoadingMask(); - showCmdExecuteTimeoutToast(); - }); + ((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedModeBtn); + hideLoadingMask(); + showCmdExecuteTimeoutToast(); } }; @@ -436,19 +443,17 @@ public class SweeperOperatePanelView extends LinearLayout { @Override public void onCmdSuccess() { - runOnUIThread(() -> { - ((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedDirectionBtn); - toggleCleanDirectionBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedDirectionBtn); - if (isClickCurrentChoosedDirectionBtn) { - toggleCleanIntensityBtnsStatus(false); - } else { - toggleCleanIntensityBtnsStatus(true); - // 一并设置作业强度为标准 - setCleanIntensityStandard(); - } - hideLoadingMask(); - showCmdExecuteSuccessToast(); - }); + ((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedDirectionBtn); + toggleCleanDirectionBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedDirectionBtn); + if (isClickCurrentChoosedDirectionBtn) { + toggleCleanIntensityBtnsStatus(false); + } else { + toggleCleanIntensityBtnsStatus(true); + // 一并设置作业强度为标准 + setCleanIntensityStandard(); + } + hideLoadingMask(); + showCmdExecuteSuccessToast(); } @Override @@ -457,11 +462,9 @@ public class SweeperOperatePanelView extends LinearLayout { @Override public void onCmdTimeout() { - runOnUIThread(() -> { - ((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedDirectionBtn); - hideLoadingMask(); - showCmdExecuteTimeoutToast(); - }); + ((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedDirectionBtn); + hideLoadingMask(); + showCmdExecuteTimeoutToast(); } }; if (isClickCurrentChoosedDirectionBtn) { @@ -526,16 +529,14 @@ public class SweeperOperatePanelView extends LinearLayout { @Override public void onCmdSuccess() { - runOnUIThread(() -> { - ((CheckedTextView) currentClickView).setChecked(true); - if (isStandardBtnClick) { - setCleanIntensityStandard(); - } else { - setCleanIntensityStrong(); - } - hideLoadingMask(); - showCmdExecuteSuccessToast(); - }); + ((CheckedTextView) currentClickView).setChecked(true); + if (isStandardBtnClick) { + setCleanIntensityStandard(); + } else { + setCleanIntensityStrong(); + } + hideLoadingMask(); + showCmdExecuteSuccessToast(); } @Override @@ -544,11 +545,9 @@ public class SweeperOperatePanelView extends LinearLayout { @Override public void onCmdTimeout() { - runOnUIThread(() -> { - ((CheckedTextView) currentClickView).setChecked(false); - hideLoadingMask(); - showCmdExecuteTimeoutToast(); - }); + ((CheckedTextView) currentClickView).setChecked(false); + hideLoadingMask(); + showCmdExecuteTimeoutToast(); } }; int cmdValue = cleanIntensityBtnAndCmdValueMap.get(currentClickView.getId()); @@ -655,39 +654,29 @@ public class SweeperOperatePanelView extends LinearLayout { * @param timeout */ private void showLoadingMask(int timeout) { - showLoadingMask("执行中,请稍后。。。", timeout); - } - - /** - * 发送命令后等待时,展示loading - * - * @param hint - * @param timeout - */ - private void showLoadingMask(String hint, int timeout) { - runOnUIThread(() -> { - mLoadingContainer.setVisibility(View.VISIBLE); - mLoadingHintTop.setText(hint); - mLoadingHintBottom.setText( - String.format( - getContext().getApplicationContext().getString(R.string.sweeper_operate_panel_cmd_execute_timeout), - timeout - )); - mLoadingHintBottom.setVisibility(timeout < 0 ? View.INVISIBLE : View.VISIBLE); - if (cleaningModeStateCallback != null && timeout > 0) { - cleaningModeStateCallback.cleaningModeState(OperateStateEnum.STARTING_STATUS, mCurrentCleanSystemState, isSelectPureSweepMode); - } - }); + mLoadingContainer.setVisibility(View.VISIBLE); + mWorkmodePanelRootView.setInterceptTouchEvent(true); + if (timeout < 0) {//状态同步中 + mLoadingHint.setText("状态同步中,请稍后"); + mLoadingView.setVisibility(View.GONE); + } else { + mLoadingHint.setText(timeout + "s"); + mLoadingView.setVisibility(View.VISIBLE); + startRotation(); + } + if (cleaningModeStateCallback != null && timeout > 0) { + operateStateEnum = OperateStateEnum.STARTING_STATUS; + cleaningModeStateCallback.cleaningModeState(operateStateEnum, mCurrentCleanSystemState, isSelectPureSweepMode); + } } /** * 隐藏loading */ private void hideLoadingMask() { - runOnUIThread(() -> { - mSweeperOperateCmdHandler.removeMessages(MSG_CMD_EXECUTE_COUNT_DOWN); - mLoadingContainer.setVisibility(View.GONE); - }); + mSweeperOperateCmdHandler.removeMessages(MSG_CMD_EXECUTE_COUNT_DOWN); + mLoadingContainer.setVisibility(View.GONE); + mWorkmodePanelRootView.setInterceptTouchEvent(false); } /** @@ -696,13 +685,7 @@ public class SweeperOperatePanelView extends LinearLayout { * @param timeout */ private void updateLoadingCountDown(int timeout) { - runOnUIThread(() -> { - mLoadingHintBottom.setText( - String.format( - getContext().getApplicationContext().getString(R.string.sweeper_operate_panel_cmd_execute_timeout), - timeout - )); - }); + mLoadingHint.setText(timeout + "s"); } /** @@ -710,8 +693,11 @@ public class SweeperOperatePanelView extends LinearLayout { */ private void showCmdExecuteSuccessToast() { if (cleaningModeStateCallback != null) { - cleaningModeStateCallback.cleaningModeState(OperateStateEnum.SUCCESS_STATUS, mCurrentCleanSystemState, isSelectPureSweepMode); + operateStateEnum = OperateStateEnum.SUCCESS_STATUS; + cleaningModeStateCallback.cleaningModeState(operateStateEnum, mCurrentCleanSystemState, isSelectPureSweepMode); } + //停止旋转动画 + stopRotation(); ToastUtils.showLong("设备已响应,操作成功"); } @@ -719,18 +705,15 @@ public class SweeperOperatePanelView extends LinearLayout { * 命令执行超时toast */ private void showCmdExecuteTimeoutToast() { + if (cleaningModeStateCallback != null) { + operateStateEnum = OperateStateEnum.FAIL_STATUS; + cleaningModeStateCallback.cleaningModeState(operateStateEnum, mCurrentCleanSystemState, isSelectPureSweepMode); + } + //停止旋转动画 + stopRotation(); ToastUtils.showLong("超时未响应,操作失败"); } - private void runOnUIThread(Runnable runnable) { - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - runnable.run(); - } - }); - } - private void setClickListener(View view, OnClickListener listener) { view.setOnClickListener(new OnPreventFastClickListener() { @Override @@ -743,7 +726,6 @@ public class SweeperOperatePanelView extends LinearLayout { public void setSweeperFutianCleanSystemState(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState, CleaningModeStateCallback cleaningModeStateCallback) { this.cleaningModeStateCallback = cleaningModeStateCallback; - onSyncVehicleStateCallBack(cleanSystemState); // 有命令正在执行 if (mCurrentCmdRequestCallback != null) { Log.d(TAG, "getSecuWorkLeftSts = " + cleanSystemState.getSecuWorkLeftSts()); @@ -752,17 +734,28 @@ public class SweeperOperatePanelView extends LinearLayout { mCurrentCmdRequestCallback = null; } } + //正在上装中或者上装失败,则不更新面板内容 + if (operateStateEnum == OperateStateEnum.STARTING_STATUS) { + return; + } + if (!isFirst) { + isFirst = true; + onSyncVehicleStateCallBack(cleanSystemState); + } } - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - // 最终调试时需要打开 - //syncVehicleStateAndRecoverOperatePanelStates(); - // Mock VehicleState 数据回调 - // UiThreadHandler.postDelayed(() -> { -// onSyncVehicleStateCallBack(SweeperFutianCmdUtil.buildSweeperFuTionCleanSystemStateMockData()); -// }, 3000L); + /** + * 设置是否展示状态同步中 + * + * @param operateState + */ + public void showSyncing(OperateStateEnum operateState) { + if (operateState == OperateStateEnum.SYNCING_STATUS) { + syncVehicleStateAndRecoverOperatePanelStates(); + isFirst = false; + } else { + hideLoadingMask(); + } } /** @@ -770,7 +763,7 @@ public class SweeperOperatePanelView extends LinearLayout { */ private synchronized void syncVehicleStateAndRecoverOperatePanelStates() { // show sync loading - showLoadingMask("状态同步中,请稍后", -1); + showLoadingMask(-1); } private synchronized void onSyncVehicleStateCallBack(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) { @@ -879,7 +872,7 @@ public class SweeperOperatePanelView extends LinearLayout { msg.obj = timeout; mSweeperOperateCmdHandler.sendMessage(msg); // Mock Cmd Success - mockCleanModeSuccess(fuTianCleanCmd); + //mockCleanModeSuccess(fuTianCleanCmd); } private void mockSendCmdSuccess() { @@ -901,23 +894,6 @@ public class SweeperOperatePanelView extends LinearLayout { + "[clean_intensity_requirement = " + clean_intensity_requirement + "]" ); } - /** - * 发送指令 - */ - private void sendFuTianTaskCmd(SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd fuTianTaskCmd) { - //mock - mockCleanModeSuccess(fuTianTaskCmd); - CallerAutoPilotControlManager.INSTANCE.sendSweeperFuTianTaskCmd(fuTianTaskCmd); - // log发送命令 - logSweeperCmdValue(fuTianTaskCmd); - } - - /** - * 重置成功 - */ - private void resetSuccess(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) { - onSyncVehicleStateCallBack(cleanSystemState); - } private final static SweeperOperateCmdHandler mSweeperOperateCmdHandler = new SweeperOperateCmdHandler(); private static CmdRequestCallback mCurrentCmdRequestCallback;//发送命令后的回调 @@ -975,12 +951,62 @@ public class SweeperOperatePanelView extends LinearLayout { void onCmdTimeout(); } + /** + * 开始旋转 + */ + private void startRotation() { + if (objectAnimator == null) { + objectAnimator = ObjectAnimator.ofFloat(mLoadingView, "rotation", 0, 360f); + objectAnimator.setDuration(1500); + objectAnimator.setRepeatCount(-1); + objectAnimator.setInterpolator(new LinearInterpolator()); + objectAnimator.start(); + } + } + + /** + * 停止旋转 + */ + private void stopRotation() { + if (objectAnimator != null && objectAnimator.isRunning()) { + objectAnimator.end(); + objectAnimator = null; + } + } + /** * 模拟指令操作成功 */ private void mockCleanModeSuccess(SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd fuTianTaskCmd) { ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.Builder builder = ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.newBuilder(); chassis.SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd fuTianCleanCmd = fuTianTaskCmd.getRoboSweeperFutianCleanCmd(); + if (fuTianCleanCmd.getCleanOpenRequirement() == CLEAN_WORK_OPEN) {//打开 + builder.setSecuMotWorkSts(true); + builder.setSecuModWashSweepSts(false); + builder.setSecuModWashSts(false); + builder.setSecuWorkTonSts(false); + builder.setSecuWorkOnBothsidesSts(false); + builder.setSecuWorkLeftSts(false); + builder.setSecuWorkRightSts(false); + builder.setSecuWorkStandSts(true); + builder.setSecuWorkStrongSts(false); + mCurrentCleanSystemState = builder.build(); + mockSendCmdSuccess(); + return; + } else if (fuTianCleanCmd.getCleanOpenRequirement() == CLEAN_WORK_CLOSE) {//关闭 + builder.setSecuModWashSweepSts(false); + builder.setSecuModWashSts(false); + builder.setSecuWorkTonSts(false); + builder.setSecuWorkOnBothsidesSts(false); + builder.setSecuWorkLeftSts(false); + builder.setSecuWorkRightSts(false); + builder.setSecuWorkStandSts(true); + builder.setSecuWorkStrongSts(false); + builder.setSecuMotWorkSts(false); + mCurrentCleanSystemState = builder.build(); + mockSendCmdSuccess(); + return; + } if (fuTianCleanCmd.getCleanModeRequirement() == CLEAN_MODE_PURE_SWEEP) {//纯扫 builder.setSecuModWashSweepSts(false); builder.setSecuModWashSts(false); diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/adapter/TaskListAdapter.kt b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/adapter/TaskListAdapter.kt index 1c6a1f5798..6e11288167 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/adapter/TaskListAdapter.kt +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/adapter/TaskListAdapter.kt @@ -11,7 +11,6 @@ import androidx.recyclerview.widget.RecyclerView import com.mogo.och.common.module.utils.DateTimeUtil import com.mogo.och.sweeper.R import com.mogo.och.sweeper.bean.SweeperMainTaskBean -import com.mogo.och.sweeper.constant.SubTaskTypeEnum class TaskListAdapter( private val context: Context, diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/popwindow/SweeperOperatePanelPopWindow.kt b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/popwindow/SweeperOperatePanelPopWindow.kt index b32ce8b15c..17f5fae813 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/popwindow/SweeperOperatePanelPopWindow.kt +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/popwindow/SweeperOperatePanelPopWindow.kt @@ -6,32 +6,28 @@ import android.graphics.drawable.ColorDrawable import android.view.LayoutInflater import android.view.ViewGroup import android.widget.PopupWindow -import android.widget.TextView import chassis.ChassisStatesOuterClass import com.mogo.och.sweeper.R import com.mogo.och.sweeper.callback.CleaningModeStateCallback +import com.mogo.och.sweeper.constant.OperateStateEnum import com.mogo.och.sweeper.ui.SweeperOperatePanelView /** * 清扫车面板浮窗 */ -class SweeperOperatePanelPopWindow : PopupWindow { +class SweeperOperatePanelPopWindow : PopupWindow{ private var mOperatePanelView: SweeperOperatePanelView? = null constructor(context: Context) : super(context) { init(context) } - private fun init(context: Context) { setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) mOperatePanelView = LayoutInflater.from(context).inflate(R.layout.sweeper_popwindow_operate_panel, null) as SweeperOperatePanelView? width = ViewGroup.LayoutParams.WRAP_CONTENT height = ViewGroup.LayoutParams.WRAP_CONTENT contentView = mOperatePanelView - isFocusable = true - isOutsideTouchable = true - isTouchable=true } /** @@ -43,4 +39,21 @@ class SweeperOperatePanelPopWindow : PopupWindow { ) { mOperatePanelView?.setSweeperFutianCleanSystemState(cleanSystemState, cleaningModeStateCallback) } + + /**. + * + * 设置是否让popWindow消失 + */ + fun setIsOutsideTouchable(isOutsideTouchable:Boolean){ + this.isFocusable = isOutsideTouchable + this.isOutsideTouchable = isOutsideTouchable + this.isTouchable=isOutsideTouchable + } + + /** + * 设置是否展示状态同步中 + */ + fun showSyncing(operateState: OperateStateEnum){ + mOperatePanelView?.showSyncing(operateState) + } } \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/util/SweeperFutianCmdUtil.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/util/SweeperFutianCmdUtil.java index 86f4f50752..79932ae4d2 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/util/SweeperFutianCmdUtil.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/util/SweeperFutianCmdUtil.java @@ -7,8 +7,8 @@ import chassis.SpecialVehicleTaskCmdOuterClass; * 清扫车-福田,构建业务命令数据的工具类 */ public class SweeperFutianCmdUtil { - private static final int CLEAN_WORK_OPEN = 1; //清扫作业-开启 - private static final int CLEAN_WORK_CLOSE = 2;//清扫作业-关闭 + public static final int CLEAN_WORK_OPEN = 1; //清扫作业-开启 + public static final int CLEAN_WORK_CLOSE = 2;//清扫作业-关闭 public static final int CLEAN_MODE_PURE_SWEEP = 1;//作业模式-纯扫 public static final int CLEAN_MODE_WASH_SWEEP = 2;//作业模式-洗扫 public static final int CLEAN_MODE_PURE_WASH = 3;//作业模式-纯洗 diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/NoTouchConstraintLayout.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/NoTouchConstraintLayout.java index 6922b9596f..2bdbd938e0 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/NoTouchConstraintLayout.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/NoTouchConstraintLayout.java @@ -6,14 +6,14 @@ import android.view.MotionEvent; import androidx.constraintlayout.widget.ConstraintLayout; -import com.mogo.commons.debug.DebugConfig; - /** * 强制拦截所有touch时间的约束布局 * * @author tongchenfei */ public class NoTouchConstraintLayout extends ConstraintLayout { + private boolean interceptTouchEvent = false; + public NoTouchConstraintLayout(Context context) { super(context); } @@ -28,10 +28,18 @@ public class NoTouchConstraintLayout extends ConstraintLayout { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if(DebugConfig.isDebug()){ - return super.onInterceptTouchEvent(ev); - }else { + if (interceptTouchEvent) { return true; } + return false; + } + + /** + * 设置事件拦截 + * + * @param interceptTouchEvent + */ + public void setInterceptTouchEvent(boolean interceptTouchEvent) { + this.interceptTouchEvent = interceptTouchEvent; } } diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/NoTouchFrameLayout.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/NoTouchFrameLayout.java new file mode 100644 index 0000000000..48b45b27af --- /dev/null +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/NoTouchFrameLayout.java @@ -0,0 +1,30 @@ +package com.mogo.och.sweeper.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.FrameLayout; + +/** + * 强制拦截所有touch时间的约束布局 + * + * @author tongchenfei + */ +public class NoTouchFrameLayout extends FrameLayout { + public NoTouchFrameLayout(Context context) { + super(context); + } + + public NoTouchFrameLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NoTouchFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return false; + } +} diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperCurrentTaskInfoView.kt b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperCurrentTaskInfoView.kt index d0f6b714f9..7fd7812e50 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperCurrentTaskInfoView.kt +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperCurrentTaskInfoView.kt @@ -77,8 +77,8 @@ class SweeperCurrentTaskInfoView : ConstraintLayout { /** * 设置准备就绪按钮时都可以点击 */ - fun setEnableClickBtn(text:String,isClick:Boolean,isTaskWorking:Boolean) { - if (mSubTaskType==SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE){ + fun setEnableClickBtn(isClick:Boolean,isPause:Boolean) { + if (mSubTaskType.code==SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE.code){ tvTaskState.text="暂未准备" tvTaskState.setBackgroundResource(R.drawable.bg_shape_task_state_not_ready) readyTaskBtn.text="准备出发" @@ -86,11 +86,15 @@ class SweeperCurrentTaskInfoView : ConstraintLayout { readyTaskBtn.isSelected=false isStartTask=false }else{ - readyTaskBtn.text=text + if (isPause){ + readyTaskBtn.text="暂停任务" + }else{ + readyTaskBtn.text="准备出发" + } readyTaskBtn.isClickable=isClick readyTaskBtn.isSelected=isClick - isStartTask=isTaskWorking - if (isTaskWorking){ + isStartTask=isPause + if (isPause){ tvTaskState.text="正在作业" tvTaskState.setBackgroundResource(R.drawable.bg_shape_task_state_working) }else{ diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.kt b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.kt index 097286098d..d88dd74abb 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.kt +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.kt @@ -1,5 +1,6 @@ package com.mogo.och.sweeper.view +import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater @@ -17,8 +18,10 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoSweeperFutianCleanSystemL import com.mogo.eagle.core.function.call.autopilot.* import com.mogo.eagle.core.function.hmi.ui.widget.TapPositionView import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d +import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant import com.mogo.eagle.core.utilcode.util.ThreadUtils import com.mogo.och.sweeper.R +import com.mogo.och.sweeper.presenter.SweeperPresenter import planning.RoboSweeperTaskIndexOuterClass /** @@ -47,6 +50,14 @@ class SweeperTrafficDataView : ConstraintLayout, private val TAG = "SweeperTrafficDataView" + // 底盘数据回调时间间隔 + private val VEHICLE_STATE_INTERVAL_MILLIS = 500L + + // 当前时间戳 + private var mCurrentTimeWaterMillis: Long = 0 + + private var mCurrentTimeBatteryMillis: Long = 0 + constructor(context: Context) : super(context) {} constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { initView(context) @@ -68,24 +79,32 @@ class SweeperTrafficDataView : ConstraintLayout, override fun onAttachedToWindow() { super.onAttachedToWindow() + //电量 CallerBatteryManagementSystemListenerManager.addListener(TAG, this) + //转向灯 CallerChassisLamplightListenerManager.addListener(TAG, this) + //档位 CallerChassisGearStateListenerManager.addListener(TAG, this) + //清扫车相关数据接口 CallerSweeperFutianCleanSystemListenerManager.addListener(TAG, this) } override fun onDetachedFromWindow() { super.onDetachedFromWindow() CallerBatteryManagementSystemListenerManager.removeListener(TAG ) - CallerChassisSteeringStateListenerManager.removeListener(TAG) CallerChassisLamplightListenerManager.removeListener(TAG) CallerChassisGearStateListenerManager.removeListener(TAG) - CallerChassisThrottleStateListenerManager.removeListener(TAG) CallerSweeperFutianCleanSystemListenerManager.removeListener(TAG) } override fun onSweeperFutianTaskIndexData(roboSweeperTaskIndex: RoboSweeperTaskIndexOuterClass.RoboSweeperTaskIndex) {} override fun onSweeperFutianCleanSystemState(cleanSystemState: SweeperFuTianTaskSystemStates) { + val current = System.currentTimeMillis() + if (current - mCurrentTimeWaterMillis <=VEHICLE_STATE_INTERVAL_MILLIS) { + return + } + mCurrentTimeWaterMillis = current + d(SceneConstant.M_SWEEPER + TAG, "水位:${cleanSystemState.hasSecuCleanWaterTankLow()}") if (cleanSystemState.hasSecuCleanWaterTankLow()) { //清水箱水位低不能清洗作业报警信号 ivBgWaterWarning?.visibility = VISIBLE ivWater?.isSelected = true @@ -95,24 +114,24 @@ class SweeperTrafficDataView : ConstraintLayout, } } + @SuppressLint("SetTextI18n") override fun onBatteryManagementSystemStates(states: BMSSystemStates) { - tvBattery?.text = String.format("%s%", states.bmsSoc) + val current = System.currentTimeMillis() + if (current - mCurrentTimeBatteryMillis <=VEHICLE_STATE_INTERVAL_MILLIS) { + return + } + mCurrentTimeBatteryMillis = current + d(SceneConstant.M_SWEEPER + TAG, "电量:${states.bmsSoc}") + tvBattery?.text = "${states.bmsSoc*100}%" } /** * 车辆转向灯 - * @param lightSwitch + * @param directionLight */ override fun onAutopilotLightSwitchData(lightSwitch: LightSwitch?) { //转向灯状态 0是正常 1是左转 2是右转 if (lightSwitch != null) { - d(TAG, "车辆转向灯:$lightSwitch") - if (lightSwitch.number == 1) { - sweeperTurnSignal?.showLeftSignal() - } else if (lightSwitch.number == 2) { - sweeperTurnSignal?.showRightSignal() - } else { - sweeperTurnSignal?.showDirection() - } + sweeperTurnSignal?.setTurnLight(lightSwitch) } } diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperWorkModeView.kt b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperWorkModeView.kt index 96533fa27d..e1dfbf38c1 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperWorkModeView.kt +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperWorkModeView.kt @@ -6,6 +6,9 @@ import android.view.LayoutInflater import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import chassis.ChassisStatesOuterClass.SweeperFuTianTaskSystemStates +import com.elegant.utils.UiThreadHandler +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d +import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant import com.mogo.och.sweeper.R import com.mogo.och.sweeper.callback.CleaningModeStateCallback import com.mogo.och.sweeper.constant.OperateStateEnum @@ -20,10 +23,12 @@ import kotlinx.android.synthetic.main.sweeper_work_mode.view.* class SweeperWorkModeView : ConstraintLayout, CleaningModeStateCallback { private var isSelectPureSweepMode: Boolean = false - + private val TAG = "SweeperWorkModeView" //清扫模式选择面板 private var mOperatePanelPopWindow: SweeperOperatePanelPopWindow? = null + private var operateState: OperateStateEnum=OperateStateEnum.SYNCING_STATUS + constructor(context: Context) : super(context) {} constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { initView(context) @@ -35,24 +40,43 @@ class SweeperWorkModeView : ConstraintLayout, CleaningModeStateCallback { private fun initView(context: Context) { LayoutInflater.from(context).inflate(R.layout.sweeper_work_mode, this) mOperatePanelPopWindow = SweeperOperatePanelPopWindow(context) + setShowOrHideCleanSystemState(OperateStateEnum.SYNCING_STATUS,null) } + /** + * 设置view + */ + fun setTrafficDataView(trafficDataView: SweeperTrafficDataView){ + //清扫模式选择面板打开关闭处理 + ivOpenOperatePanel.setOnClickListener { + if (mOperatePanelPopWindow?.isShowing != true) { + mOperatePanelPopWindow?.showAsDropDown( + trafficDataView, + resources.getDimension(R.dimen.dp_600).toInt(), + 0 + ) + UiThreadHandler.postDelayed({ + d(SceneConstant.M_SWEEPER + TAG, "operateState:"+operateState.code) + mOperatePanelPopWindow?.showSyncing(operateState) + + },300) + } else { + mOperatePanelPopWindow?.dismiss() + } + } + } /** * 设置清扫模式面板 */ - fun setSweeperFutianCleanSystemState(taskType: SubTaskTypeEnum, cleanSystemState: SweeperFuTianTaskSystemStates?, trafficDataView: SweeperTrafficDataView) { + fun setSweeperFutianCleanSystemState(taskType: SubTaskTypeEnum, cleanSystemState: SweeperFuTianTaskSystemStates?) { mOperatePanelPopWindow?.setCleanSystemState(cleanSystemState, this@SweeperWorkModeView) - //清扫模式选择面板打开关闭处理 - ivOpenOperatePanel.setOnClickListener { - if (mOperatePanelPopWindow?.isShowing != true) { - mOperatePanelPopWindow?.showAsDropDown( - trafficDataView, - resources.getDimension(R.dimen.dp_600).toInt(), - 0 - ) - } else { - mOperatePanelPopWindow?.dismiss() - } + if (this.operateState.code==OperateStateEnum.STARTING_STATUS.code){ + return + } + //如果状态是同步中,在底盘首次回调时把状态强制修改成成功 + if (this.operateState.code==OperateStateEnum.SYNCING_STATUS.code){ + this.operateState=OperateStateEnum.SUCCESS_STATUS + d(SceneConstant.M_SWEEPER + TAG, "SystemState operateState:"+operateState.code) } //清扫车暂未选择清扫模式或者任务类型是人工驾驶子任务,则暂无清扫模式 if (SweeperFutianCmdUtil.checkIfCleanMode(cleanSystemState) || taskType.code == SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE.code) { @@ -65,32 +89,37 @@ class SweeperWorkModeView : ConstraintLayout, CleaningModeStateCallback { /** * 设置清扫模式状态显示和隐藏 */ - fun setShowOrHideCleanSystemState(operateState: OperateStateEnum, cleanSystemState: SweeperFuTianTaskSystemStates?) { + private fun setShowOrHideCleanSystemState(operateState: OperateStateEnum, cleanSystemState: SweeperFuTianTaskSystemStates?) { when (operateState.code) { OperateStateEnum.SYNCING_STATUS.code -> { groupWorkModelPanel?.visibility = View.GONE tvNoDataDesc?.visibility = View.VISIBLE tvNoDataDesc?.text = "状态同步中,请稍后" + mOperatePanelPopWindow?.setIsOutsideTouchable(true) } OperateStateEnum.FAIL_STATUS.code -> { groupWorkModelPanel?.visibility = View.GONE tvNoDataDesc?.visibility = View.VISIBLE tvNoDataDesc?.text = "上装启动失败" + mOperatePanelPopWindow?.setIsOutsideTouchable(true) } OperateStateEnum.STARTING_STATUS.code -> { groupWorkModelPanel?.visibility = View.GONE tvNoDataDesc?.visibility = View.VISIBLE tvNoDataDesc?.text = "上装启动中..." + mOperatePanelPopWindow?.setIsOutsideTouchable(false) } OperateStateEnum.NO_STATUS.code -> { groupWorkModelPanel?.visibility = View.GONE tvNoDataDesc?.visibility = View.VISIBLE tvNoDataDesc?.text = "暂无" + mOperatePanelPopWindow?.setIsOutsideTouchable(true) } else -> { groupWorkModelPanel?.visibility = View.VISIBLE tvNoDataDesc?.visibility = View.GONE setCleanModeData(cleanSystemState) + mOperatePanelPopWindow?.setIsOutsideTouchable(true) } } @@ -98,6 +127,7 @@ class SweeperWorkModeView : ConstraintLayout, CleaningModeStateCallback { override fun cleaningModeState(operateState: OperateStateEnum, cleanSystemState: SweeperFuTianTaskSystemStates?, isSelectPureSweepMode: Boolean) { this.isSelectPureSweepMode = isSelectPureSweepMode + this.operateState=operateState setShowOrHideCleanSystemState(operateState, cleanSystemState) } diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/TurnSignalView.kt b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/TurnSignalView.kt index 23c6d1dc1f..863521c446 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/TurnSignalView.kt +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/TurnSignalView.kt @@ -1,11 +1,20 @@ package com.mogo.och.sweeper.view +import android.animation.AnimatorSet +import android.animation.ObjectAnimator import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater +import android.view.View +import android.widget.ImageView import android.widget.LinearLayout +import chassis.Chassis +import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager import com.mogo.och.sweeper.R import kotlinx.android.synthetic.main.sweeper_turn_signal.view.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch class TurnSignalView : LinearLayout { constructor(context: Context?) : super(context) {} @@ -13,34 +22,58 @@ class TurnSignalView : LinearLayout { initView(context) } + private var init: Boolean = false + constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {} constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {} private fun initView(context: Context) { LayoutInflater.from(context).inflate(R.layout.sweeper_turn_signal, this) + init = true } /** - * 展示左转向灯 + * 转向灯动画 */ - fun showLeftSignal() { - turnLeftView?.isSelected = true - turnRightView?.isSelected = false + fun setTurnLight(directionLight: Chassis.LightSwitch?) { + GlobalScope.launch(Dispatchers.Main) { + if (!init) { + return@launch + } + //根据左右进行显示和隐藏,实际要判断每个来的时间和频度 + when (directionLight) { + Chassis.LightSwitch.LIGHT_LEFT -> { //左转向 + CallerVisualAngleManager.changeVisualAngle(CallerVisualAngleManager.Scene.Turning(true)) + leftSelectImage.visibility = View.VISIBLE + rightSelectImage.visibility = View.GONE + rightSelectImage.clearAnimation() + setAnimation(leftSelectImage) + } + Chassis.LightSwitch.LIGHT_RIGHT -> { //右转向 + CallerVisualAngleManager.changeVisualAngle(CallerVisualAngleManager.Scene.Turning(true)) + leftSelectImage.visibility = View.GONE + rightSelectImage.visibility = View.VISIBLE + leftSelectImage.clearAnimation() + setAnimation(rightSelectImage) + } + else -> { //消失 + CallerVisualAngleManager.changeVisualAngle(CallerVisualAngleManager.Scene.Turning(false)) + leftSelectImage.clearAnimation() + rightSelectImage.clearAnimation() + } + } + } } - - /** - * 展示右转向灯 - */ - fun showRightSignal() { - turnLeftView?.isSelected = false - turnRightView?.isSelected = true - } - - /** - * 默认情况及其直行时 - */ - fun showDirection() { - turnLeftView?.isSelected = false - turnRightView?.isSelected = false + //实现图片闪烁效果 + private fun setAnimation(imageView: ImageView) { + val animationSet = AnimatorSet() + val valueAnimator = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1.0f) + val valueAnimatorDisappare = ObjectAnimator.ofFloat(imageView, "alpha", 1.0f, 0f) + valueAnimator.duration = 1000 + valueAnimatorDisappare.duration = 800 + valueAnimator.repeatCount = -1 + valueAnimatorDisappare.repeatCount = -1 + animationSet.playTogether(valueAnimatorDisappare, valueAnimator) + animationSet.start() } } \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/src/main/res/drawable-xhdpi/sweeper_loading_nor.png b/OCH/mogo-och-sweeper/src/main/res/drawable-xhdpi/sweeper_loading_nor.png new file mode 100644 index 0000000000..0ff5309fab Binary files /dev/null and b/OCH/mogo-och-sweeper/src/main/res/drawable-xhdpi/sweeper_loading_nor.png differ diff --git a/OCH/mogo-och-sweeper/src/main/res/layout/fragment_och_sweeper.xml b/OCH/mogo-och-sweeper/src/main/res/layout/fragment_och_sweeper.xml index 4e387255f5..c1f255a8f0 100644 --- a/OCH/mogo-och-sweeper/src/main/res/layout/fragment_och_sweeper.xml +++ b/OCH/mogo-och-sweeper/src/main/res/layout/fragment_och_sweeper.xml @@ -1,93 +1,119 @@ - - + + + + + - - - - + - + android:layout_height="match_parent"> + + + + + - + - - - - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_base_fragment.xml b/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_base_fragment.xml index 197a7bc82e..53990820c5 100644 --- a/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_base_fragment.xml +++ b/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_base_fragment.xml @@ -86,29 +86,6 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> - - - - - + android:background="@drawable/bg_sweeper_operate_panel" + android:id="@+id/work_mode_panel_root_view"> + + app:layout_constraintTop_toTopOf="parent" /> + + app:layout_constraintTop_toBottomOf="@+id/btn_clean_work_open_close" /> + app:layout_constraintTop_toBottomOf="@id/hint_clean_mode" /> + app:layout_constraintTop_toBottomOf="@id/hint_clean_mode" /> + app:layout_constraintTop_toBottomOf="@id/hint_clean_mode" /> + app:layout_constraintTop_toBottomOf="@id/hint_clean_mode" /> @@ -151,6 +151,8 @@ android:id="@+id/btn_clean_direction_left_side" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/dp_90" + android:layout_marginTop="@dimen/dp_17" android:background="@drawable/sweeper_operate_panel_btn2_bg_selector" android:enabled="false" android:gravity="center" @@ -158,19 +160,18 @@ android:paddingTop="@dimen/dp_12" android:paddingEnd="@dimen/dp_48" android:paddingBottom="@dimen/dp_12" - android:layout_marginStart="@dimen/dp_90" - android:textColor="@color/white" android:text="左侧" + android:textColor="@color/white" android:textSize="@dimen/sweeper_operate_panel_btn_text_size" - app:layout_constraintTop_toBottomOf="@+id/hint_clean_direction" app:layout_constraintStart_toStartOf="parent" - android:layout_marginTop="@dimen/dp_17"/> + app:layout_constraintTop_toBottomOf="@+id/hint_clean_direction" /> + app:layout_constraintStart_toEndOf="@+id/btn_clean_direction_left_side" + app:layout_constraintTop_toBottomOf="@+id/hint_clean_direction" /> @@ -215,9 +215,9 @@ android:id="@+id/hint_clean_intensity" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/dp_90" android:layout_marginTop="@dimen/dp_48" android:gravity="top|center_horizontal" - android:layout_marginStart="@dimen/dp_90" android:text="作业强度" android:textColor="@color/white" android:textSize="@dimen/sweeper_operate_panel_btn_text_size" @@ -228,6 +228,8 @@ android:id="@+id/btn_clean_intensity_standard" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/dp_90" + android:layout_marginTop="@dimen/dp_17" android:background="@drawable/sweeper_operate_panel_btn2_bg_selector" android:enabled="false" android:gravity="center" @@ -235,12 +237,10 @@ android:paddingTop="@dimen/dp_12" android:paddingEnd="@dimen/dp_48" android:paddingBottom="@dimen/dp_12" - android:layout_marginStart="@dimen/dp_90" - android:textColor="@color/white" - android:layout_marginTop="@dimen/dp_17" android:text="标准" + android:textColor="@color/white" android:textSize="@dimen/sweeper_operate_panel_btn_text_size" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/hint_clean_intensity" /> - - + - - - \ No newline at end of file + + + \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_turn_signal.xml b/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_turn_signal.xml index 2af09a3830..6ad67d647f 100644 --- a/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_turn_signal.xml +++ b/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_turn_signal.xml @@ -1,18 +1,36 @@ - + android:layout_height="match_parent"> + android:layout_gravity="left|center_vertical" + android:src="@drawable/turn_signal_left_nor" /> + - \ No newline at end of file + android:layout_gravity="right|center_vertical" + android:src="@drawable/turn_signal_right_nor" /> + + + + + \ No newline at end of file