feat(ui): 添加PLC控制设置界面

- 新增PLC设置界面布局文件,包含连接控制、出盘操作、平台控制等功能模块
- 在AndroidManifest.xml中注册PlcSettingActivity组件
- 为初始化和人脸识别登录页面添加右键双击打开PLC设置的功能
- 实现完整的PLC设置活动类,集成串口通信、自动模式、出盘、平台升降等控制功能
- 添加参数设置输入验证和状态信息实时显示功能
- 实现故障复位和状态刷新等关键操作接口
This commit is contained in:
mazengfei
2026-03-30 18:17:49 +08:00
parent 83f9654987
commit cc16fcecff
5 changed files with 567 additions and 0 deletions
+3
View File
@@ -64,6 +64,9 @@
android:name=".activity.MainActivity"
android:exported="false">
</activity>
<activity
android:name=".activity.PlcSettingActivity"
android:exported="false" />
<!-- <activity android:name="com.sw.platecabinet.activity.FunActivity" />-->
</application>
@@ -41,4 +41,8 @@ class InitActivity : BaseActivity<ActivityInitBinding>() {
finish()
}
override fun onRightDoubleClick() {
PlcSettingActivity.start(this)
}
}
@@ -188,6 +188,10 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
finish()
}
override fun onRightDoubleClick() {
PlcSettingActivity.start(this)
}
private var isRecognition = false
private var rgbCameraHelper: DualCameraHelper? = null
private var rgbFaceRectTransformer: FaceRectTransformer? = null
@@ -0,0 +1,287 @@
package com.sw.platecabinet.activity
import android.content.Context
import android.content.Intent
import android.view.inputmethod.InputMethodManager
import com.sw.plate.utils.ToastUtils
import com.sw.platecabinet.databinding.ActivityPlcSettingBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.ext.clickWithDebounce
import com.sw.platecabinet.utils.mego.PlcCallback
import com.sw.platecabinet.utils.mego.PlcHelper
import com.sw.platecabinet.utils.mego.PlcStatus
/**
* PLC 控制设置界面
* 通过右侧时间双击(onRightDoubleClick)打开,提供全套 PLC 控制操作入口
*/
class PlcSettingActivity : BaseActivity<ActivityPlcSettingBinding>() {
companion object {
/**
* 启动 PlcSettingActivity
*/
fun start(context: Context) {
context.startActivity(Intent(context, PlcSettingActivity::class.java))
}
}
override fun inflateViewBinding(): ActivityPlcSettingBinding {
return ActivityPlcSettingBinding.inflate(layoutInflater)
}
override fun inflateTitleBinding(): ItemTitleTimeBinding {
return binding.includeHeader
}
override fun initialize() {
initConnectButtons()
initOutPlateButton()
initPlatformButtons()
initAlarmButton()
initParamButtons()
initStatusButton()
}
// ==================== 连接控制 ====================
/**
* 初始化连接控制区按钮:打开串口、打开自动模式
*/
private fun initConnectButtons() {
binding.btnOpenSerialPort.clickWithDebounce {
showWaitingDialog("正在打开串口……")
PlcHelper.getInstance(this).openSerialPort(object : PlcCallback<String> {
override fun onSuccess(result: String) {
hideWaitingDialog()
ToastUtils.showToast("打开串口成功:$result")
}
override fun onError(message: String) {
hideWaitingDialog()
ToastUtils.showToast("打开串口失败:$message")
}
})
}
binding.btnOpenAutoMode.clickWithDebounce {
showWaitingDialog("正在打开自动模式……")
PlcHelper.getInstance(this).openAutoMode(object : PlcCallback<String> {
override fun onSuccess(result: String) {
hideWaitingDialog()
ToastUtils.showToast("打开自动模式成功:$result")
}
override fun onError(message: String) {
hideWaitingDialog()
ToastUtils.showToast("打开自动模式失败:$message")
}
})
}
}
// ==================== 出盘操作 ====================
/**
* 初始化出盘操作按钮
*/
private fun initOutPlateButton() {
binding.btnOutPlate.clickWithDebounce {
showWaitingDialog("正在出盘……")
PlcHelper.getInstance(this).outPlate(object : PlcCallback<String> {
override fun onSuccess(result: String) {
hideWaitingDialog()
ToastUtils.showToast("出盘成功:$result")
}
override fun onError(message: String) {
hideWaitingDialog()
ToastUtils.showToast("出盘失败:$message")
}
})
}
}
// ==================== 平台控制 ====================
/**
* 初始化平台控制区按钮:平台下降、平台上升、返回营业
*/
private fun initPlatformButtons() {
binding.btnPlatformDown.clickWithDebounce {
showWaitingDialog("正在执行平台下降……")
PlcHelper.getInstance(this).platformDown(object : PlcCallback<String> {
override fun onSuccess(result: String) {
hideWaitingDialog()
ToastUtils.showToast("平台下降成功:$result")
}
override fun onError(message: String) {
hideWaitingDialog()
ToastUtils.showToast("平台下降失败:$message")
}
})
}
binding.btnPlatformUp.clickWithDebounce {
showWaitingDialog("正在执行平台上升……")
PlcHelper.getInstance(this).platformUp(object : PlcCallback<String> {
override fun onSuccess(result: String) {
hideWaitingDialog()
ToastUtils.showToast("平台上升成功:$result")
}
override fun onError(message: String) {
hideWaitingDialog()
ToastUtils.showToast("平台上升失败:$message")
}
})
}
binding.btnBackToBusiness.clickWithDebounce {
showWaitingDialog("正在返回营业状态……")
PlcHelper.getInstance(this).backToBusiness(object : PlcCallback<String> {
override fun onSuccess(result: String) {
hideWaitingDialog()
ToastUtils.showToast("返回营业成功:$result")
}
override fun onError(message: String) {
hideWaitingDialog()
ToastUtils.showToast("返回营业失败:$message")
}
})
}
}
// ==================== 故障处理 ====================
/**
* 初始化故障复位按钮
*/
private fun initAlarmButton() {
binding.btnAlarmReset.clickWithDebounce {
showWaitingDialog("正在故障复位……")
PlcHelper.getInstance(this).alarmReset(object : PlcCallback<String> {
override fun onSuccess(result: String) {
hideWaitingDialog()
ToastUtils.showToast("故障复位成功:$result")
}
override fun onError(message: String) {
hideWaitingDialog()
ToastUtils.showToast("故障复位失败:$message")
}
})
}
}
// ==================== 参数设置 ====================
/**
* 初始化参数设置按钮
* 读取参数类型和参数值输入框内容,调用 setParams
*/
private fun initParamButtons() {
binding.btnSetParams.clickWithDebounce {
val paramType = binding.etParamType.text.toString().trim()
val paramValueStr = binding.etParamValue.text.toString().trim()
if (paramType.isEmpty()) {
ToastUtils.showToast("请输入参数类型")
return@clickWithDebounce
}
if (paramValueStr.isEmpty()) {
ToastUtils.showToast("请输入参数值")
return@clickWithDebounce
}
val paramValue = paramValueStr.toIntOrNull()
if (paramValue == null) {
ToastUtils.showToast("参数值须为整数")
return@clickWithDebounce
}
// 隐藏键盘
hideKeyboard()
showWaitingDialog("正在设置参数……")
PlcHelper.getInstance(this).setParams(
paramType,
paramValue,
object : PlcCallback<String> {
override fun onSuccess(result: String) {
hideWaitingDialog()
ToastUtils.showToast("参数设置成功:$result")
}
override fun onError(message: String) {
hideWaitingDialog()
ToastUtils.showToast("参数设置失败:$message")
}
}
)
}
}
// ==================== 状态显示 ====================
/**
* 初始化状态刷新按钮,获取 PLC 状态并格式化展示
*/
private fun initStatusButton() {
binding.btnRefreshStatus.clickWithDebounce {
showWaitingDialog("正在获取状态……")
PlcHelper.getInstance(this).getStatus(object : PlcCallback<PlcStatus> {
override fun onSuccess(result: PlcStatus) {
hideWaitingDialog()
binding.tvStatusInfo.text = buildStatusText(result)
}
override fun onError(message: String) {
hideWaitingDialog()
binding.tvStatusInfo.text = "获取状态失败:$message"
ToastUtils.showToast("获取状态失败:$message")
}
})
}
}
/**
* 将 PlcStatus 格式化为多行可读文本
*/
private fun buildStatusText(status: PlcStatus): String {
return """
空盘状态:${if (status.isEmptyPlate) "是(无餐盘)" else "否(有餐盘)"}
平台下位:${if (status.isPlateformDown) "是" else "否"}
平台上位:${if (status.isPlateformUp) "是" else "否"}
取盘红外:${if (status.isTakePlateInfrared) "已触发" else "未触发"}
报警代码:${if (status.alarmCode == 0) "正常(0" else "异常(${status.alarmCode}"}
""".trimIndent()
}
// ==================== 生命周期 ====================
/**
* 左侧日期双击 → 关闭设置界面
*/
override fun onLeftDoubleClick() {
finish()
}
/**
* 右侧时间双击 → 不做操作,防止循环打开
*/
override fun onRightDoubleClick() {
// 空实现,避免在设置页再次触发跳转
}
// ==================== 工具方法 ====================
/**
* 隐藏软键盘
*/
private fun hideKeyboard() {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0)
}
}
@@ -0,0 +1,269 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"
android:orientation="vertical"
tools:context=".activity.PlcSettingActivity">
<include
android:id="@+id/includeHeader"
layout="@layout/item_title_time" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:paddingHorizontal="50dp"
android:paddingVertical="20dp"
android:clipToPadding="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- ===== 连接控制 ===== -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="连接控制"
android:textColor="#FFCC99"
android:textSize="20sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/btnOpenSerialPort"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="打开串口"
android:textColor="#FFCC99"
android:textSize="22sp" />
<View
android:layout_width="20dp"
android:layout_height="1dp" />
<TextView
android:id="@+id/btnOpenAutoMode"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="打开自动模式"
android:textColor="#FFCC99"
android:textSize="22sp" />
</LinearLayout>
<!-- ===== 出盘操作 ===== -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="出盘操作"
android:textColor="#FFCC99"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/btnOutPlate"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="出盘"
android:textColor="#FFCC99"
android:textSize="22sp" />
<!-- ===== 平台控制 ===== -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="平台控制"
android:textColor="#FFCC99"
android:textSize="20sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/btnPlatformDown"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="平台下降"
android:textColor="#FFCC99"
android:textSize="22sp" />
<View
android:layout_width="20dp"
android:layout_height="1dp" />
<TextView
android:id="@+id/btnPlatformUp"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="平台上升"
android:textColor="#FFCC99"
android:textSize="22sp" />
</LinearLayout>
<TextView
android:id="@+id/btnBackToBusiness"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="12dp"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="返回营业(补盘完成)"
android:textColor="#FFCC99"
android:textSize="22sp" />
<!-- ===== 故障处理 ===== -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="故障处理"
android:textColor="#FFCC99"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/btnAlarmReset"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="故障复位"
android:textColor="#FFCC99"
android:textSize="22sp" />
<!-- ===== 参数设置 ===== -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="参数设置"
android:textColor="#FFCC99"
android:textSize="20sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<EditText
android:id="@+id/etParamType"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:background="@drawable/btn_outline"
android:gravity="center"
android:hint="参数类型(如 18FD"
android:inputType="text"
android:paddingHorizontal="12dp"
android:textColor="#FFCC99"
android:textColorHint="#99885566"
android:textSize="18sp" />
<View
android:layout_width="20dp"
android:layout_height="1dp" />
<EditText
android:id="@+id/etParamValue"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:background="@drawable/btn_outline"
android:gravity="center"
android:hint="参数值(整数)"
android:inputType="number"
android:paddingHorizontal="12dp"
android:textColor="#FFCC99"
android:textColorHint="#99885566"
android:textSize="18sp" />
</LinearLayout>
<TextView
android:id="@+id/btnSetParams"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="12dp"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="设置参数"
android:textColor="#FFCC99"
android:textSize="22sp" />
<!-- ===== 状态显示 ===== -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="PLC 状态"
android:textColor="#FFCC99"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/btnRefreshStatus"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:background="@drawable/btn_outline"
android:gravity="center"
android:text="刷新状态"
android:textColor="#FFCC99"
android:textSize="22sp" />
<TextView
android:id="@+id/tvStatusInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="@drawable/btn_outline"
android:paddingHorizontal="16dp"
android:paddingVertical="14dp"
android:text="暂无状态数据"
android:textColor="#FFCC99"
android:textSize="16sp"
tools:text="空盘:false | 平台下位:false | 平台上位:true | 取盘红外:false | 报警码:0" />
<View
android:layout_width="match_parent"
android:layout_height="30dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>