From 7ab8e09a462090dbcd49e9e0d01d252a966985e8 Mon Sep 17 00:00:00 2001 From: mazengfei <331023091@qq.com> Date: Fri, 3 Jul 2026 14:57:25 +0800 Subject: [PATCH] =?UTF-8?q?refactor(scale):=20=E4=BC=98=E5=8C=96=E4=B8=B2?= =?UTF-8?q?=E5=8F=A3=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=92=8C=E8=87=AA=E5=8A=A8=E5=BA=94=E7=AD=94=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在串口数据读取中增加帧拼装与解析,统一自动应答发送 - 实现心跳日志降频,减少重复日志,避免主线程无效计算 - 将数据回调分派至主线程,确保线程安全 - 缓存时间格式化器,避免重复创建对象 - 增加秤重数据变更判断,避免无变化时刷新UI和日志 - 异步优化文件日志写入,使用协程通道和单线程写入,避免多线程SimpleDateFormat竞争 - 修复文件路径和上下文使用,防止Activity内存泄漏 - 精简部分注释和代码未使用段落,提高代码清晰度 --- .../shelves/serial/ScaleManager.kt | 281 ++++++++---------- .../intelligent/shelves/utils/FileLogger.kt | 148 ++++----- .../sw/scalefusion/shelf/HomeV3Activity.kt | 6 + .../sw/scalefusion/shelf/ShelfV3Activity.kt | 8 +- .../shelf/adapter/ShelfV3Adapter.kt | 4 - 5 files changed, 194 insertions(+), 253 deletions(-) diff --git a/app/src/main/java/com/shuwei/intelligent/shelves/serial/ScaleManager.kt b/app/src/main/java/com/shuwei/intelligent/shelves/serial/ScaleManager.kt index 4411d28..566a023 100644 --- a/app/src/main/java/com/shuwei/intelligent/shelves/serial/ScaleManager.kt +++ b/app/src/main/java/com/shuwei/intelligent/shelves/serial/ScaleManager.kt @@ -166,10 +166,23 @@ object ScaleManager { val flow = serialPort?.read() flow?.collect { buffer -> val data = buffer.toHexString2().uppercase(Locale.ROOT) + // IO 线程:帧拼装与解析 + val parsed = tryParseCompleteFrame(data) + if (parsed != null) { + // IO 线程:发送自动应答(不占用主线程) + sendAutoResponse(parsed.first) + // IO 线程:心跳日志降频 + if (parsed.first.cmd == CMD_HEARTBEAT || parsed.first.cmd == CMD_HEARTBEAT_STORE) { + logHeartbeatIfNeeded(parsed.first, parsed.second) + } + } + // 仅回调分发和 preHook 需要主线程 withContext(Dispatchers.Main) { try { preHook?.invoke(data) - onDataReceived(data) + if (parsed != null) { + invokeCallbacks(parsed.first) + } } catch (e: Exception) { e.printStackTrace() log("串口数据处理异常: ${e.message}") @@ -179,7 +192,7 @@ object ScaleManager { } catch (e: Exception) { e.printStackTrace() } - delay(50) + delay(10) } } } @@ -189,19 +202,117 @@ object ScaleManager { // ---------------------------------------------------------------- /** - * 接收串口原始数据(在串口回调中调用此方法) + * 接收串口原始数据(公开 API,主线程安全) * - * 内部自动完成分片拼装 → 帧解析 → 命令分发 → 自动应答 + * 内部自动完成分片拼装 → 帧解析 → 自动应答 → 回调分发 * * @param hexData 串口收到的十六进制字符串(可能为分片数据) */ fun onDataReceived(hexData: String) { - val completeFrame = parser.appendData(hexData) ?: return - val frame = parser.parseFrame(completeFrame) ?: run { + val parsed = tryParseCompleteFrame(hexData) ?: return + sendAutoResponse(parsed.first) + invokeCallbacks(parsed.first) + } + + /** + * IO 线程安全的帧拼装与解析(纯计算,无副作用) + * + * @return Pair 或 null(分片未完整/解析失败) + */ + private fun tryParseCompleteFrame(hexData: String): Pair? { + val completeFrame = parser.appendData(hexData) ?: return null + val frame = parser.parseFrame(completeFrame) + if (frame == null) { log("帧解析失败,原始数据:$completeFrame") - return } - dispatch(frame, completeFrame) + return frame?.let { it to completeFrame } + } + + /** + * IO 线程:发送协议自动应答(不阻塞主线程) + */ + private fun sendAutoResponse(frame: ScaleFrame) { + when (frame.cmd) { + CMD_HEARTBEAT, CMD_HEARTBEAT_STORE -> { + val firmwareHex = frame.firmwareVersion.toAsciiHex() + val resp = "${HEADER_HEX}0102%02X%02X${firmwareHex}${FOOTER_HEX}".format( + heartbeatInterval and 0xFF, lockTimeout and 0xFF + ) + sendCmd(resp) + } + CMD_UNLOCK -> { + val terminalIdHex = frame.terminalId.toAsciiHex() + val firmwareHex = frame.firmwareVersion.toAsciiHex() + sendCmd("${HEADER_HEX}020200${terminalIdHex}${firmwareHex}${FOOTER_HEX}") + } + CMD_CARD_UPLOAD -> sendCmd("${HEADER_HEX}050203${FOOTER_HEX}") + CMD_OPERATION_RECORD -> sendCmd("${HEADER_HEX}0B0203${FOOTER_HEX}") + CMD_TEMP_REPORT -> sendCmd("${HEADER_HEX}100200${FOOTER_HEX}") + CMD_POSITION_REPORT -> sendCmd("${HEADER_HEX}0E0200${FOOTER_HEX}") + CMD_TIME_SYNC -> { + val nowMs = System.currentTimeMillis() + val timeSec = nowMs / 1000 + TimeZone.getDefault().getOffset(nowMs) / 1000 + val timeHex = "%08X".format(timeSec.toInt()) + .chunked(2).reversed().joinToString("") + sendCmd("${HEADER_HEX}0C02${timeHex}${FOOTER_HEX}") + } + CMD_ACTIVATE -> { + if (activateCode.isNotBlank()) sendCmd(activateCode) + } + } + } + + /** + * 主线程:仅回调分发(不含 sendCmd 和日志) + */ + private fun invokeCallbacks(frame: ScaleFrame) { + when (frame.cmd) { + CMD_ACTIVATE -> { + activateListeners.forEach { it(frame) } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + CMD_HEARTBEAT, CMD_HEARTBEAT_STORE -> { + val data = parser.parseHeartbeat(frame.rawBody) + if (data != null) { + heartbeatListeners.forEach { it(frame, data) } + } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + CMD_UNLOCK -> { + lockListeners.forEach { it(frame) } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + CMD_GET_STATUS -> { + val data = parser.parseStatus(frame.rawBody) + if (data != null) { + statusListeners.forEach { it(frame, data) } + } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + CMD_CARD_UPLOAD -> { + cardListeners.forEach { it(frame) } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + CMD_OPERATION_RECORD -> { + operationListeners.forEach { it(frame) } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + CMD_TIME_SYNC -> { + timeSyncListeners.forEach { it(frame) } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + CMD_POSITION_REPORT -> { + positionListeners.forEach { it(frame) } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + CMD_TEMP_REPORT -> { + tempReportListeners.forEach { it(frame) } + rawListeners[frame.cmd]?.forEach { it(frame) } + } + else -> { + rawListeners[frame.cmd]?.forEach { it(frame) } + } + } } // ---------------------------------------------------------------- @@ -443,164 +554,28 @@ object ScaleManager { rawListeners.clear() logListeners.clear() activateCode = "" + lastHeartbeatLogSecond = 0 parser.reset() } // ---------------------------------------------------------------- - // 内部命令分发与自动应答 + // 日志与工具 // ---------------------------------------------------------------- - private fun dispatch(frame: ScaleFrame, rawHex: String) { - when (frame.cmd) { - CMD_ACTIVATE -> handleActivate(frame, rawHex) - CMD_HEARTBEAT, - CMD_HEARTBEAT_STORE -> handleHeartbeat(frame, rawHex) - CMD_UNLOCK -> handleLockFeedback(frame, rawHex) - CMD_GET_STATUS -> handleStatus(frame, rawHex) - CMD_CARD_UPLOAD -> handleCardUpload(frame, rawHex) - CMD_OPERATION_RECORD -> handleOperationRecord(frame, rawHex) - CMD_TIME_SYNC -> handleTimeSync(frame, rawHex) - CMD_POSITION_REPORT -> handlePositionReport(frame, rawHex) - CMD_TEMP_REPORT -> handleTempReport(frame, rawHex) - else -> { - rawListeners[frame.cmd]?.forEach { it(frame) } - log("收到未处理命令:0x%02X,终端ID:${frame.terminalId},原始数据:$rawHex".format(frame.cmd)) - } - } - } + /** 上次心跳日志时间(秒),用于降频:同一秒内不重复记录心跳日志 */ + private var lastHeartbeatLogSecond: Long = 0 /** - * 处理终端激活(CMD=0x00) - * 若 activateMap 中存在当前 deviceId 对应的激活码,则自动应答; - * 否则仍回调 onActivate,由业务方自行处理 + * IO 线程:心跳日志降频 — 每秒最多记录一次 */ - private fun handleActivate(frame: ScaleFrame, rawHex: String) { - log("收到[终端激活]指令,终端ID:${frame.terminalId},固件版本:${frame.firmwareVersion},原始数据:$rawHex") - val activeCmd = activateCode - if (!activeCmd.isNullOrBlank()) { - sendCmd(activeCmd) - log("激活码自动应答:$activeCmd") - } - activateListeners.forEach { it(frame) } - rawListeners[frame.cmd]?.forEach { it(frame) } - } - - /** - * 处理心跳(CMD=0x01 / 0x81) - * 自动应答:[心跳间隔] [上锁时间] [设备固件版本5字节] - */ - private fun handleHeartbeat(frame: ScaleFrame, rawHex: String) { - val firmwareHex = frame.firmwareVersion.toAsciiHex() - val resp = "${HEADER_HEX}0102%02X%02X${firmwareHex}${FOOTER_HEX}".format( - heartbeatInterval and 0xFF, - lockTimeout and 0xFF - ) - sendCmd(resp) - + private fun logHeartbeatIfNeeded(frame: ScaleFrame, rawHex: String) { + val nowSec = System.currentTimeMillis() / 1000 + if (nowSec == lastHeartbeatLogSecond) return + lastHeartbeatLogSecond = nowSec val data = parser.parseHeartbeat(frame.rawBody) - if (data != null) { - heartbeatListeners.forEach { it(frame, data) } - } - rawListeners[frame.cmd]?.forEach { it(frame) } log("收到[心跳]指令,终端ID:${frame.terminalId},秤数量:${data?.scaleCount ?: 0},原始数据:$rawHex") } - /** - * 处理开锁反馈(CMD=0x02,终端发起,关门后上报) - * 自动应答:[锁号00] [终端ID 15字节] [固件版本 5字节] - */ - private fun handleLockFeedback(frame: ScaleFrame, rawHex: String) { - val terminalIdHex = frame.terminalId.toAsciiHex() - val firmwareHex = frame.firmwareVersion.toAsciiHex() - val resp = "${HEADER_HEX}020200${terminalIdHex}${firmwareHex}${FOOTER_HEX}" - sendCmd(resp) - lockListeners.forEach { it(frame) } - rawListeners[frame.cmd]?.forEach { it(frame) } - log("收到[开锁反馈]指令,终端ID:${frame.terminalId},原始数据:$rawHex") - } - - /** - * 处理获取状态响应(CMD=0x03,终端响应) - * 无需应答,直接解析并分发 - */ - private fun handleStatus(frame: ScaleFrame, rawHex: String) { - val data = parser.parseStatus(frame.rawBody) - if (data != null) { - statusListeners.forEach { it(frame, data) } - } - rawListeners[frame.cmd]?.forEach { it(frame) } - log("收到[获取状态]响应,终端ID:${frame.terminalId},秤数量:${data?.scaleCount ?: 0},原始数据:$rawHex") - } - - /** - * 处理卡号上发(CMD=0x05,终端发起) - * 自动应答:成功 0x03 - */ - private fun handleCardUpload(frame: ScaleFrame, rawHex: String) { - val resp = "${HEADER_HEX}050203${FOOTER_HEX}" - sendCmd(resp) - cardListeners.forEach { it(frame) } - rawListeners[frame.cmd]?.forEach { it(frame) } - log("收到[卡号上发]指令,终端ID:${frame.terminalId},原始数据:$rawHex") - } - - /** - * 处理操作记录上传(CMD=0x0B,终端发起) - * 自动应答:成功 0x03 - */ - private fun handleOperationRecord(frame: ScaleFrame, rawHex: String) { - val resp = "${HEADER_HEX}0B0203${FOOTER_HEX}" - sendCmd(resp) - operationListeners.forEach { it(frame) } - rawListeners[frame.cmd]?.forEach { it(frame) } - log("收到[操作记录上传]指令,终端ID:${frame.terminalId},原始数据:$rawHex") - } - - /** - * 处理对时请求(CMD=0x0C,终端发起,仅以太网版本) - * 自动应答:当前 Unix 时间戳(含时区偏移),小端序4字节 - */ - private fun handleTimeSync(frame: ScaleFrame, rawHex: String) { - val nowMs = System.currentTimeMillis() - val timeSec = nowMs / 1000 + TimeZone.getDefault().getOffset(nowMs) / 1000 - // 取低32位,转为小端序4字节十六进制 - val timeHex = "%08X".format(timeSec.toInt()) - .chunked(2).reversed().joinToString("") - val resp = "${HEADER_HEX}0C02${timeHex}${FOOTER_HEX}" - sendCmd(resp) - timeSyncListeners.forEach { it(frame) } - rawListeners[frame.cmd]?.forEach { it(frame) } - log("收到[对时]请求,终端ID:${frame.terminalId},时间戳:${timeSec},应答:$resp") - } - - /** - * 处理终端位置上报(CMD=0x0E,终端发起,仅4G版本) - * 自动应答:保留字节 0x00 - */ - private fun handlePositionReport(frame: ScaleFrame, rawHex: String) { - val resp = "${HEADER_HEX}0E0200${FOOTER_HEX}" - sendCmd(resp) - positionListeners.forEach { it(frame) } - rawListeners[frame.cmd]?.forEach { it(frame) } - log("收到[终端位置上报]指令,终端ID:${frame.terminalId},原始数据:$rawHex") - } - - /** - * 处理温控信息上报(CMD=0x10,终端发起) - * 自动应答:保留字节 0x00 - */ - private fun handleTempReport(frame: ScaleFrame, rawHex: String) { - val resp = "${HEADER_HEX}100200${FOOTER_HEX}" - sendCmd(resp) - tempReportListeners.forEach { it(frame) } - rawListeners[frame.cmd]?.forEach { it(frame) } - log("收到[温控信息上报]指令,终端ID:${frame.terminalId},原始数据:$rawHex") - } - - // ---------------------------------------------------------------- - // 私有工具 - // ---------------------------------------------------------------- - private fun log(message: String) { logListeners.forEach { it(message) } } diff --git a/app/src/main/java/com/shuwei/intelligent/shelves/utils/FileLogger.kt b/app/src/main/java/com/shuwei/intelligent/shelves/utils/FileLogger.kt index 0047d5c..4e9958a 100644 --- a/app/src/main/java/com/shuwei/intelligent/shelves/utils/FileLogger.kt +++ b/app/src/main/java/com/shuwei/intelligent/shelves/utils/FileLogger.kt @@ -1,131 +1,91 @@ package com.shuwei.intelligent.shelves.utils import android.content.Context -import com.shuwei.intelligent.shelves.utils.CrashHandler.Companion.CRASH_REPORTS_DIR +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.Channel import java.io.* import java.text.SimpleDateFormat import java.util.* - /** - * 文件日志记录器 - * 功能:保存日志到本地文件,每条数据一行,每天生成新文件 + * 文件日志记录器(异步版) + * + * log() 仅投递原始消息到 Channel(任意线程安全), + * 格式化与文件写入在单一后台协程顺序执行,避免 SimpleDateFormat 多线程竞争。 */ -class FileLogger(private val context: Context) { +class FileLogger(context: Context) { companion object { - private const val LOG_DIR = "logs" private const val FILE_PREFIX = "log_" private const val FILE_EXTENSION = ".txt" - private val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) - private val timeFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) + + /** 全局单线程日志写入 */ + private val logChannel = Channel(capacity = Channel.UNLIMITED) + private val writerScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + + init { + writerScope.launch { + // 单协程顺序消费:SimpleDateFormat 在此线程安全 + val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) + val timeFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) + for (entry in logChannel) { + try { + val fileName = "${FILE_PREFIX}${dateFormat.format(Date())}${FILE_EXTENSION}" + val timestamp = timeFormat.format(Date()) + val logLine = "[$timestamp] [${entry.level}] ${entry.message}\n" + val output = entry.appContext.openFileOutput( + fileName, Context.MODE_APPEND + ) + BufferedWriter(OutputStreamWriter(output)).use { it.write(logLine) } + } catch (_: Exception) { + // 写入失败静默丢弃 + } + } + } + } + + private data class RawEntry( + val appContext: Context, + val message: String, + val level: LogLevel + ) } + /** 持有 ApplicationContext 避免 Activity 泄漏 */ + private val appContext: Context = context.applicationContext + /** - * 记录日志 - * @param message 日志消息 - * @param level 日志级别 + * 记录日志(异步,线程安全) */ fun log(message: String, level: LogLevel = LogLevel.INFO) { - try { - val logEntry = formatLogEntry(message, level) - writeToFile(logEntry) - } catch (e: IOException) { - e.printStackTrace() - } + logChannel.trySend(RawEntry(appContext, message, level)) } - /** - * 格式化日志条目 - */ - private fun formatLogEntry(message: String, level: LogLevel): String { - val timestamp = timeFormat.format(Date()) - return "[$timestamp] [$level] $message\n" - } - - /** - * 写入文件 - */ - private fun writeToFile(logEntry: String) { -// val path = File(context.filesDir, LOG_DIR) -// if (path.exists().not()) { -// path.mkdirs() -// } - val fileName = getCurrentDateFileName() -// val file = File(path, fileName) -// if (file.exists().not()) { -// file.createNewFile() -// } - val output = context.openFileOutput(fileName, Context.MODE_APPEND) - - val writer = BufferedWriter(OutputStreamWriter(output)) - writer.use { - it.write(logEntry) - } - } - - /** - * 获取当前日期对应的文件名 - */ - private fun getCurrentDateFileName(): String { - val date = dateFormat.format(Date()) - return "${FILE_PREFIX}${date}${FILE_EXTENSION}" - } - - /** - * 读取指定日期的日志文件 - * @param date 日期字符串,格式:yyyy-MM-dd - */ fun readLogsByDate(date: String): List { - val fileName = "${FILE_PREFIX}${date}${FILE_EXTENSION}" - return readLogsByName(fileName) + return readLogsByName("${FILE_PREFIX}${date}${FILE_EXTENSION}") } + fun readLogsByName(fileName: String): List { try { - val input = context.openFileInput(fileName) + val input = appContext.openFileInput(fileName) val reader = BufferedReader(InputStreamReader(input)) - val list: MutableList = reader.useLines { lines -> - lines.toList().toMutableList() - } - -// val input2 = FileInputStream(getCrashDir(context)) -// val reader2 = BufferedReader(InputStreamReader(input2)) -// val list2: MutableList = reader2.useLines {lines -> -// lines.toList().toMutableList() -// } -// list.addAll(list2) - return list - } catch (e: FileNotFoundException) { + return reader.useLines { lines -> lines.toList().toMutableList() } + } catch (_: FileNotFoundException) { return emptyList() } } - public fun getCrashDir(context: Context):File { - //val crashDir = File(context.getExternalFilesDir(null), CRASH_REPORTS_DIR) - var crashDir = File(context.filesDir, CRASH_REPORTS_DIR) - if (!crashDir.exists()) { - crashDir.mkdirs() - } - - if (!(crashDir.exists())) { - crashDir = File(context.cacheDir, CRASH_REPORTS_DIR) - } + fun getCrashDir(context: Context): File { + var crashDir = File(context.filesDir, "crash_reports") + if (!crashDir.exists()) crashDir.mkdirs() + if (!crashDir.exists()) crashDir = File(context.cacheDir, "crash_reports") return crashDir } - /** - * 获取所有日志文件列表 - */ fun getLogFiles(): List { - return context.fileList() + return appContext.fileList() .filter { it.startsWith(FILE_PREFIX) && it.endsWith(FILE_EXTENSION) } - //.map { it.replace(FILE_EXTENSION, "") } } - /** - * 日志级别枚举 - */ - enum class LogLevel { - DEBUG, INFO, WARN, ERROR - } + enum class LogLevel { DEBUG, INFO, WARN, ERROR } } diff --git a/app/src/main/java/com/sw/scalefusion/shelf/HomeV3Activity.kt b/app/src/main/java/com/sw/scalefusion/shelf/HomeV3Activity.kt index b1da6f5..cf9834b 100644 --- a/app/src/main/java/com/sw/scalefusion/shelf/HomeV3Activity.kt +++ b/app/src/main/java/com/sw/scalefusion/shelf/HomeV3Activity.kt @@ -74,6 +74,9 @@ class HomeV3Activity : BaseActivity() { private val viewModel: NetViewModelV3 by viewModels() + /** 记录每台秤的上次重量(克),用于跳过无变化的 UI 刷新和日志 */ + private val lastWeightGrams = mutableMapOf() + private fun initScaleManager() { lifecycleScope.launch { val ok = ScaleManager @@ -81,6 +84,9 @@ class HomeV3Activity : BaseActivity() { .onHeartbeat { _, data -> data.weights.forEach { weight -> val pos = scaleIndexToPosition[weight.index] ?: return@forEach + // 重量不变则跳过 UI 刷新、日志和 EventBus,避免主线程无效计算 + if (lastWeightGrams[weight.index] == weight.grams) return@forEach + lastWeightGrams[weight.index] = weight.grams val model = list[pos] model.weight = weight.grams / 1000.0 shelfAdapter.notifyItemChanged(pos) diff --git a/app/src/main/java/com/sw/scalefusion/shelf/ShelfV3Activity.kt b/app/src/main/java/com/sw/scalefusion/shelf/ShelfV3Activity.kt index 71a4b04..7a56a25 100644 --- a/app/src/main/java/com/sw/scalefusion/shelf/ShelfV3Activity.kt +++ b/app/src/main/java/com/sw/scalefusion/shelf/ShelfV3Activity.kt @@ -55,6 +55,11 @@ class ShelfV3Activity : BaseActivity() { const val YYYY_MM_DD__EEEE_HH_MM_SS = "yyyy年MM月dd日 EEEE***HH:mm:ss" } + /** 缓存的日期格式化器,避免 onClockTick 每秒 new 对象 */ + private val clockFormatter by lazy { + SimpleDateFormat(YYYY_MM_DD__EEEE_HH_MM_SS, Locale.CHINA) + } + private lateinit var binding: ActivityShelfV3Binding private var shelfModel: SlotModel? = null @@ -327,8 +332,7 @@ class ShelfV3Activity : BaseActivity() { } override fun onClockTick() { - val sdf = SimpleDateFormat(YYYY_MM_DD__EEEE_HH_MM_SS, Locale.CHINA) - val arr = sdf.format(Date()).split("***") + val arr = clockFormatter.format(Date()).split("***") updateLeftStatus(arr[0]) updateRightStatus(arr[1]) } diff --git a/app/src/main/java/com/sw/scalefusion/shelf/adapter/ShelfV3Adapter.kt b/app/src/main/java/com/sw/scalefusion/shelf/adapter/ShelfV3Adapter.kt index 493b1a0..421c97a 100644 --- a/app/src/main/java/com/sw/scalefusion/shelf/adapter/ShelfV3Adapter.kt +++ b/app/src/main/java/com/sw/scalefusion/shelf/adapter/ShelfV3Adapter.kt @@ -42,10 +42,6 @@ class ShelfV3Adapter(list: MutableList) : // 格口编号 binding.tvShelfName.text = item.slotNo.padStart(2, '0') -// // 临期预警(slotStatus=2)显示过期图标 -// if (item.slotStatus.toInt() == 2) binding.ivStaleFood.visible() -// else binding.ivStaleFood.gone() - val weightG = item.weight ?: 0.0 binding.tvFoodWeight.run { setTextColor(getColor(R.color.food_weight_orange))