From 12c6b5cf941856cece6a42bbc9fd14017c5406b8 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Wed, 6 May 2026 10:01:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(adapter):=20=E4=BF=AE=E5=A4=8D=20ScaleRowAd?= =?UTF-8?q?apter=20=E7=82=B9=E5=87=BB=E4=BA=8B=E4=BB=B6=E5=81=B6=E5=8F=91?= =?UTF-8?q?=E5=A4=B1=E6=95=88=EF=BC=8C=E6=94=B9=E7=94=A8=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9B=BF=E4=BB=A3=20submitList?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 updateItem / updateName / removeByAddress 同步更新方法,使用 set/add/removeAt 直接触发 notifyItemChanged - 新增 onItemClick lambda 属性,点击时通过 bindingAdapterPosition 取最新数据 - SlaveActivity 中所有 submitList 调用替换为对应同步方法,消除 AsyncListDiffer 异步窗口期导致的点击丢失 Co-Authored-By: Claude Sonnet 4.6 --- .../dish/match/adapter/ScaleRowAdapter.kt | 49 +++++++++++++++++++ .../com/shuwei/dish/match/ui/SlaveActivity.kt | 32 ++---------- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/shuwei/dish/match/adapter/ScaleRowAdapter.kt b/app/src/main/java/com/shuwei/dish/match/adapter/ScaleRowAdapter.kt index 50e8541..c02ed4d 100644 --- a/app/src/main/java/com/shuwei/dish/match/adapter/ScaleRowAdapter.kt +++ b/app/src/main/java/com/shuwei/dish/match/adapter/ScaleRowAdapter.kt @@ -3,6 +3,7 @@ package com.shuwei.dish.match.adapter import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView import com.chad.library.adapter4.BaseQuickAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.shuwei.dish.match.databinding.ListItemScaleRowBinding @@ -11,6 +12,8 @@ import com.shuwei.dish.match.utils.WeightUtil /** * 线性列表秤数据 Adapter * 用于 SlaveActivity 非22/18格子设备的秤列表展示 + * 通过 updateItem / updateName / removeByAddress 同步更新,避免 submitList 的 + * AsyncListDiffer 异步窗口期导致点击事件丢失 */ class ScaleRowAdapter : BaseQuickAdapter() { @@ -23,6 +26,9 @@ class ScaleRowAdapter : BaseQuickAdapter Unit)? = null + inner class VH(val b: ListItemScaleRowBinding) : QuickViewHolder(b.root) override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { @@ -40,5 +46,48 @@ class ScaleRowAdapter : BaseQuickAdapter "超量" else -> "${item.state}" } + // 点击时通过 bindingAdapterPosition 取最新数据,避免闭包捕获过期 item + holder.b.root.setOnClickListener { + val pos = holder.bindingAdapterPosition + if (pos != RecyclerView.NO_POSITION) { + items.getOrNull(pos)?.let { onItemClick?.invoke(it) } + } + } + } + + /** + * 同步更新单条秤数据:存在则定点刷新,不存在则按 address 升序插入 + * 使用 set/add 替代 submitList,消除 AsyncListDiffer 异步窗口期 + * @param item 最新秤数据 + */ + fun updateItem(item: ScaleItem) { + val idx = items.indexOfFirst { it.address == item.address } + if (idx >= 0) { + set(idx, item) + } else { + // 找到按 address 升序的插入位置 + val insertPos = items.indexOfFirst { it.address > item.address } + .let { if (it < 0) items.size else it } + add(insertPos, item) + } + } + + /** + * 同步更新指定地址的调料名称 + * @param address 秤地址 + * @param name 新名称 + */ + fun updateName(address: Int, name: String) { + val idx = items.indexOfFirst { it.address == address } + if (idx >= 0) set(idx, items[idx].copy(name = name)) + } + + /** + * 同步移除指定地址的条目 + * @param address 秤地址 + */ + fun removeByAddress(address: Int) { + val idx = items.indexOfFirst { it.address == address } + if (idx >= 0) removeAt(idx) } } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SlaveActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SlaveActivity.kt index 23f35f2..1ef5707 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SlaveActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SlaveActivity.kt @@ -125,10 +125,7 @@ class SlaveActivity : BaseActivity() { else -> { binding.rvScaleList.updateLayoutParams { topMargin = 20.dp } binding.rvScaleList.layoutManager = LinearLayoutManager(this) - linearAdapter.setOnItemClickListener { _, _, position -> - val item = linearAdapter.items.getOrNull(position) ?: return@setOnItemClickListener - showTareDialog(item.address) - } + linearAdapter.onItemClick = { item -> showTareDialog(item.address) } binding.rvScaleList.adapter = linearAdapter } } @@ -203,12 +200,8 @@ class SlaveActivity : BaseActivity() { if (pos >= 0) scale18Adapter!!.updateItemName(pos, "") } else -> { - val list = linearAdapter.items.toMutableList() - val idx = list.indexOfFirst { it.address == addr } - if (idx >= 0) { - list[idx] = list[idx].copy(name = "") - linearAdapter.submitList(list) - } + val idx = linearAdapter.items.indexOfFirst { it.address == addr } + if (idx >= 0) linearAdapter.removeByAddress(addr) } } } @@ -225,14 +218,7 @@ class SlaveActivity : BaseActivity() { val pos = ScaleDeviceConfig.SCALE_ORDER_18.indexOf(slot.address) if (pos >= 0) scale18Adapter!!.updateItemName(pos, slot.goodsName) } - else -> { - val list = linearAdapter.items.toMutableList() - val idx = list.indexOfFirst { it.address == slot.address } - if (idx >= 0) { - list[idx] = list[idx].copy(name = slot.goodsName) - linearAdapter.submitList(list) - } - } + else -> linearAdapter.updateName(slot.address, slot.goodsName) } } } @@ -272,15 +258,7 @@ class SlaveActivity : BaseActivity() { } else -> { val item = ScaleRowAdapter.ScaleItem(address, weight, state, slotNameMap[address] ?: "") - val list = linearAdapter.items.toMutableList() - val idx = list.indexOfFirst { it.address == address } - if (idx >= 0) { - list[idx] = item - } else { - list.add(item) - list.sortBy { it.address } - } - linearAdapter.submitList(list) + linearAdapter.updateItem(item) } }