fix(adapter): 修复 ScaleRowAdapter 点击事件偶发失效,改用同步更新替代 submitList
- 新增 updateItem / updateName / removeByAddress 同步更新方法,使用 set/add/removeAt 直接触发 notifyItemChanged - 新增 onItemClick lambda 属性,点击时通过 bindingAdapterPosition 取最新数据 - SlaveActivity 中所有 submitList 调用替换为对应同步方法,消除 AsyncListDiffer 异步窗口期导致的点击丢失 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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<ScaleRowAdapter.ScaleItem, ScaleRowAdapter.VH>() {
|
||||
|
||||
@@ -23,6 +26,9 @@ class ScaleRowAdapter : BaseQuickAdapter<ScaleRowAdapter.ScaleItem, ScaleRowAdap
|
||||
*/
|
||||
data class ScaleItem(val address: Int, val weight: Double, val state: Int, val name: String = "")
|
||||
|
||||
/** item 点击回调 */
|
||||
var onItemClick: ((ScaleItem) -> 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<ScaleRowAdapter.ScaleItem, ScaleRowAdap
|
||||
WeightUtil.STATE_OVER_WEIGHT -> "超量"
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,10 +125,7 @@ class SlaveActivity : BaseActivity() {
|
||||
else -> {
|
||||
binding.rvScaleList.updateLayoutParams<LinearLayout.LayoutParams> { 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user