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.content.Context
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.chad.library.adapter4.BaseQuickAdapter
|
import com.chad.library.adapter4.BaseQuickAdapter
|
||||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||||
import com.shuwei.dish.match.databinding.ListItemScaleRowBinding
|
import com.shuwei.dish.match.databinding.ListItemScaleRowBinding
|
||||||
@@ -11,6 +12,8 @@ import com.shuwei.dish.match.utils.WeightUtil
|
|||||||
/**
|
/**
|
||||||
* 线性列表秤数据 Adapter
|
* 线性列表秤数据 Adapter
|
||||||
* 用于 SlaveActivity 非22/18格子设备的秤列表展示
|
* 用于 SlaveActivity 非22/18格子设备的秤列表展示
|
||||||
|
* 通过 updateItem / updateName / removeByAddress 同步更新,避免 submitList 的
|
||||||
|
* AsyncListDiffer 异步窗口期导致点击事件丢失
|
||||||
*/
|
*/
|
||||||
class ScaleRowAdapter : BaseQuickAdapter<ScaleRowAdapter.ScaleItem, ScaleRowAdapter.VH>() {
|
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 = "")
|
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)
|
inner class VH(val b: ListItemScaleRowBinding) : QuickViewHolder(b.root)
|
||||||
|
|
||||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||||
@@ -40,5 +46,48 @@ class ScaleRowAdapter : BaseQuickAdapter<ScaleRowAdapter.ScaleItem, ScaleRowAdap
|
|||||||
WeightUtil.STATE_OVER_WEIGHT -> "超量"
|
WeightUtil.STATE_OVER_WEIGHT -> "超量"
|
||||||
else -> "${item.state}"
|
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 -> {
|
else -> {
|
||||||
binding.rvScaleList.updateLayoutParams<LinearLayout.LayoutParams> { topMargin = 20.dp }
|
binding.rvScaleList.updateLayoutParams<LinearLayout.LayoutParams> { topMargin = 20.dp }
|
||||||
binding.rvScaleList.layoutManager = LinearLayoutManager(this)
|
binding.rvScaleList.layoutManager = LinearLayoutManager(this)
|
||||||
linearAdapter.setOnItemClickListener { _, _, position ->
|
linearAdapter.onItemClick = { item -> showTareDialog(item.address) }
|
||||||
val item = linearAdapter.items.getOrNull(position) ?: return@setOnItemClickListener
|
|
||||||
showTareDialog(item.address)
|
|
||||||
}
|
|
||||||
binding.rvScaleList.adapter = linearAdapter
|
binding.rvScaleList.adapter = linearAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,12 +200,8 @@ class SlaveActivity : BaseActivity() {
|
|||||||
if (pos >= 0) scale18Adapter!!.updateItemName(pos, "")
|
if (pos >= 0) scale18Adapter!!.updateItemName(pos, "")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val list = linearAdapter.items.toMutableList()
|
val idx = linearAdapter.items.indexOfFirst { it.address == addr }
|
||||||
val idx = list.indexOfFirst { it.address == addr }
|
if (idx >= 0) linearAdapter.removeByAddress(addr)
|
||||||
if (idx >= 0) {
|
|
||||||
list[idx] = list[idx].copy(name = "")
|
|
||||||
linearAdapter.submitList(list)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,14 +218,7 @@ class SlaveActivity : BaseActivity() {
|
|||||||
val pos = ScaleDeviceConfig.SCALE_ORDER_18.indexOf(slot.address)
|
val pos = ScaleDeviceConfig.SCALE_ORDER_18.indexOf(slot.address)
|
||||||
if (pos >= 0) scale18Adapter!!.updateItemName(pos, slot.goodsName)
|
if (pos >= 0) scale18Adapter!!.updateItemName(pos, slot.goodsName)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> linearAdapter.updateName(slot.address, slot.goodsName)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -272,15 +258,7 @@ class SlaveActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val item = ScaleRowAdapter.ScaleItem(address, weight, state, slotNameMap[address] ?: "")
|
val item = ScaleRowAdapter.ScaleItem(address, weight, state, slotNameMap[address] ?: "")
|
||||||
val list = linearAdapter.items.toMutableList()
|
linearAdapter.updateItem(item)
|
||||||
val idx = list.indexOfFirst { it.address == address }
|
|
||||||
if (idx >= 0) {
|
|
||||||
list[idx] = item
|
|
||||||
} else {
|
|
||||||
list.add(item)
|
|
||||||
list.sortBy { it.address }
|
|
||||||
}
|
|
||||||
linearAdapter.submitList(list)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user