refactor(layout): 优化网格布局工具和货架界面排序逻辑

- 新增 getLayoutManagerV2 方法用于创建垂直方向的网格布局管理器
- 修改 initListSortV2 方法支持动态行列参数控制排序逻辑
- 添加 submitListSortV2 方法用于提交时按槽位号排序
- 重构 HomeV2Activity 中的 UI 更新逻辑,支持动态行列配置
- 修复 RecyclerView 初始化时机问题,避免重复设置适配器
- 优化 ShelfV2Activity 中的清空操作,添加加载提示和自动关闭功能
- 完善槽位状态管理,支持空置和存放中状态标识
This commit is contained in:
2026-06-04 14:32:08 +08:00
parent ac17fca325
commit 694e20023a
3 changed files with 98 additions and 43 deletions
@@ -125,7 +125,6 @@ class HomeV2Activity : BaseActivity() {
} }
updateLeftStatus("") updateLeftStatus("")
initRecyclerView()
// 初始化 ScaleManager:注册回调、打开串口、启动接收 // 初始化 ScaleManager:注册回调、打开串口、启动接收
initScaleManager() initScaleManager()
@@ -176,7 +175,7 @@ class HomeV2Activity : BaseActivity() {
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
private fun updateUI(data: RespData<*>) { private fun updateUI(data: RespData<*>) {
binding.include?.root?.gone() binding.include.root.gone()
window?.decorView?.postDelayed({ Loading.dismiss() }, 500) window?.decorView?.postDelayed({ Loading.dismiss() }, 500)
cabinetInitResult = data.data as? CabinetInitResult cabinetInitResult = data.data as? CabinetInitResult
if (cabinetInitResult == null) { if (cabinetInitResult == null) {
@@ -184,18 +183,27 @@ class HomeV2Activity : BaseActivity() {
loadEmptyView() loadEmptyView()
return return
} }
deviceName = cabinetInitResult!!.deviceName val cabinet = cabinetInitResult!!
//行列数量后端返回是反着的
val columns = cabinet.horizontalRows
val rows = cabinet.verticalCount
log("updateUI: rows=$rows, columns=$columns")
deviceName = cabinet.deviceName
updateLeftStatus(deviceName) updateLeftStatus(deviceName)
App.canteenId = cabinetInitResult!!.canteenId.toString() App.canteenId = cabinet.canteenId.toString()
var tempList = cabinetInitResult!!.containerGoodsList var tempList = cabinet.containerGoodsList
if (tempList.isNullOrEmpty()) { if (tempList.isNullOrEmpty()) {
loadEmptyView() loadEmptyView()
return return
} }
list.clear() list.clear()
tempList = GridLayoutTool.initListSortV2(tempList) tempList = GridLayoutTool.initListSortV2(rows = rows, columns = columns, source = tempList)
list.addAll(tempList) list.addAll(tempList)
shelfAdapter.notifyDataSetChanged() if (binding.rvShelf.adapter == null) {
initRecyclerView(columns)
} else {
shelfAdapter.notifyDataSetChanged()
}
} }
private fun showError(message: String) { private fun showError(message: String) {
@@ -312,19 +320,20 @@ class HomeV2Activity : BaseActivity() {
it.spec = model.spec it.spec = model.spec
it.foodId = model.foodId it.foodId = model.foodId
it.storeTime = model.storeTime it.storeTime = model.storeTime
it.slotStatus = model.slotStatus
} }
shelfAdapter.notifyItemChanged(position) shelfAdapter.notifyItemChanged(position)
// syncShelfGoodsToServer() // syncShelfGoodsToServer()
} }
private fun initRecyclerView() { private fun initRecyclerView(columns: Int) {
val layoutManager = GridLayoutTool.getLayoutManager(this@HomeV2Activity) ?: return val layoutManager = GridLayoutTool.getLayoutManagerV2(this, columns = columns)
binding.rvShelf.let { binding.rvShelf.let {
it.layoutManager = layoutManager it.layoutManager = layoutManager
it.adapter = shelfAdapter it.adapter = shelfAdapter
it.itemAnimator.let { it.itemAnimator.let { animator ->
if (it is DefaultItemAnimator) { if (animator is DefaultItemAnimator) {
it.supportsChangeAnimations = false animator.supportsChangeAnimations = false
} }
} }
} }
@@ -361,17 +370,17 @@ class HomeV2Activity : BaseActivity() {
// loadTestData() // loadTestData()
} }
@SuppressLint("NotifyDataSetChanged") // @SuppressLint("NotifyDataSetChanged")
private fun loadTestData() { // private fun loadTestData() {
binding.rvShelf.layoutManager = GridLayoutManager(this, 2) // binding.rvShelf.layoutManager = GridLayoutManager(this, 2)
binding.rvShelf.adapter = shelfAdapter // binding.rvShelf.adapter = shelfAdapter
binding.include.root.gone() // binding.include.root.gone()
list.clear() // list.clear()
var tempList = (1..10).map { i -> ShelfModelV2(slotNo = i.toString()) } // var tempList = (1..10).map { i -> ShelfModelV2(slotNo = i.toString()) }
tempList = GridLayoutTool.initListSortV2(tempList) // tempList = GridLayoutTool.initListSortV2(tempList)
list.addAll(tempList) // list.addAll(tempList)
shelfAdapter.notifyDataSetChanged() // shelfAdapter.notifyDataSetChanged()
} // }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun clearEmptyShelf(event: ClearShelfEvent) { fun clearEmptyShelf(event: ClearShelfEvent) {
@@ -427,18 +436,18 @@ class HomeV2Activity : BaseActivity() {
/** /**
* 构建同步请求并提交到服务端 * 构建同步请求并提交到服务端
* TODO: 待 ShelfV2Activity 迁移到 RecordItem 后重新实现
*/ */
private fun syncShelfGoodsToServer() { private fun syncShelfGoodsToServer() {
if (cabinetInitResult == null) { if (cabinetInitResult == null) {
return return
} }
val submitList = GridLayoutTool.submitListSortV2(list)
viewModelV2.syncCabinetData(SyncBody().apply { viewModelV2.syncCabinetData(SyncBody().apply {
// cabinetId = list[0].cabinetId // cabinetId = list[0].cabinetId
cabinetId = App.deviceId cabinetId = App.deviceId
temperature = null temperature = null
humidity = null humidity = null
goodsList = list goodsList = submitList
}) })
} }
} }
@@ -52,6 +52,7 @@ class ShelfV2Activity : BaseActivity() {
/** itemType=1:净菜包 */ /** itemType=1:净菜包 */
private const val TYPE_CLEAN = 1 private const val TYPE_CLEAN = 1
/** itemType=2:餐品净菜包 */ /** itemType=2:餐品净菜包 */
private const val TYPE_MEAL = 2 private const val TYPE_MEAL = 2
} }
@@ -108,7 +109,7 @@ class ShelfV2Activity : BaseActivity() {
val weightG = it.totalWeightG?.toInt() ?: 0 val weightG = it.totalWeightG?.toInt() ?: 0
realWeight = weightG realWeight = weightG
binding.tvFoodWeight.text = if (weightG < 1000) "${weightG}" binding.tvFoodWeight.text = if (weightG < 1000) "${weightG}"
else "%.3f千克".format(weightG / 1000.0) else "%.3f千克".format(weightG / 1000.0)
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
} }
@@ -137,7 +138,8 @@ class ShelfV2Activity : BaseActivity() {
} }
private fun switchAdapter() { private fun switchAdapter() {
val adapter: BaseQuickAdapter<*, *> = if (currentType == TYPE_CLEAN) cleanAdapter else mealAdapter val adapter: BaseQuickAdapter<*, *> =
if (currentType == TYPE_CLEAN) cleanAdapter else mealAdapter
binding.rvSearch.adapter = adapter binding.rvSearch.adapter = adapter
} }
@@ -168,25 +170,59 @@ class ShelfV2Activity : BaseActivity() {
private fun initButtons() { private fun initButtons() {
binding.ivBack.setOnClickListener { finish() } binding.ivBack.setOnClickListener { finish() }
binding.btnClearZero.setOnClickListener { clearZero() } binding.btnClearZero.setOnClickListener {
binding.btnClearEmpty.setOnClickListener { Loading.show(this@ShelfV2Activity)
clearZero()
window.decorView.postDelayed({ Loading.dismiss() }, 10000)
}
binding.btnClearEmpty.setOnClickListener { v ->
clearZero() clearZero()
binding.tvFoodName.text = "-" binding.tvFoodName.text = "-"
Loading.show(this@ShelfV2Activity)
v.postDelayed({
Loading.dismiss()
// 3 秒后自动关闭 Activity 并回传空值
val emptyRecord = recordItem?.also {
it.itemName = ""
//4-空置
it.slotStatus = 4
it.totalWeightG = null
it.actualQty = null
it.itemType = 0
it.traceCode = null
it.storeTime = null
it.spec = null
it.specLabel = null
it.cleanOrderNo = null
}
val result = Intent().apply {
putExtra(SHELF_MODEL, emptyRecord)
}
setResult(RESULT_OK, result)
finish()
}, 3000)
} }
binding.btnConfirm.clickWithDebounce { binding.btnConfirm.clickWithDebounce {
var shelfModelV2: ShelfModelV2?=null var shelfModelV2: ShelfModelV2? = null
if (currentType == TYPE_CLEAN) { if (currentType == TYPE_CLEAN) {
val item = cleanList.firstOrNull { it.isSelected } val item = cleanList.firstOrNull { it.isSelected }
if (item == null) { if (item == null) {
toast("请选择净菜包"); return@clickWithDebounce toast("请选择净菜包"); return@clickWithDebounce
} }
shelfModelV2 = item.toShelfModelV2(recordItem) shelfModelV2 = item.toShelfModelV2(recordItem).also {
//1-存放中
it.slotStatus = 1
}
} else { } else {
val item = mealList.firstOrNull { it.isSelected } val item = mealList.firstOrNull { it.isSelected }
if (item == null) { if (item == null) {
toast("请选择餐品净菜包"); return@clickWithDebounce toast("请选择餐品净菜包"); return@clickWithDebounce
} }
shelfModelV2 = item.toShelfModelV2(recordItem) shelfModelV2 = item.toShelfModelV2(recordItem).also {
//1-存放中
it.slotStatus = 1
}
} }
// 将选中结果回传给上层 Activity // 将选中结果回传给上层 Activity
val result = Intent().apply { val result = Intent().apply {
@@ -311,8 +347,6 @@ class ShelfV2Activity : BaseActivity() {
realWeight = 0 realWeight = 0
sendCmd(ScaleManager.buildGetStatusCmd()) sendCmd(ScaleManager.buildGetStatusCmd())
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
Loading.show(this@ShelfV2Activity)
window.decorView.postDelayed({ Loading.dismiss() }, 10000)
} }
KeyboardUtil.hideKeyboard(window.decorView) KeyboardUtil.hideKeyboard(window.decorView)
} }
@@ -342,7 +376,7 @@ class ShelfV2Activity : BaseActivity() {
val weight = event.weight val weight = event.weight
log("格口${recordItem?.slotNo}获取重量:${weight}克,间隔:${intervalTime}ms") log("格口${recordItem?.slotNo}获取重量:${weight}克,间隔:${intervalTime}ms")
binding.tvFoodWeight.text = if (weight < 1000) "${weight}" binding.tvFoodWeight.text = if (weight < 1000) "${weight}"
else "%.3f千克".format(weight / 1000.0) else "%.3f千克".format(weight / 1000.0)
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
window.decorView.postDelayed({ Loading.dismiss() }, 1000) window.decorView.postDelayed({ Loading.dismiss() }, 1000)
} }
@@ -30,6 +30,8 @@ object GridLayoutTool {
} }
} }
fun getLayoutManagerV2(context: Context, columns: Int) = GridLayoutManager(context, columns, GridLayoutManager.VERTICAL, false)
/** /**
* 初始化list显示顺序 * 初始化list显示顺序
*/ */
@@ -45,17 +47,27 @@ object GridLayoutTool {
} }
} }
fun initListSortV2(source: List<ShelfModelV2>): List<ShelfModelV2> { fun initListSortV2(rows:Int, columns:Int, source: List<ShelfModelV2>): List<ShelfModelV2> {
val map = source.associateBy { it.slotNo?.toIntOrNull()?:0 } val map = source.associateBy { it.slotNo?.toIntOrNull()?:0 }
return if (device3Columns.contains(App.deviceId)) { if (rows != 5) return source
// 按全局定义的显示顺序取对应数据,找不到则跳过 return when (columns) {
ProtocolConstants.device3ColumnsOrder.mapNotNull { map[it] } 3 -> {
} else if (device2Columns.contains(App.deviceId)) { // 3列顺序
ProtocolConstants.device2ColumnsOrder.mapNotNull { map[it] } ProtocolConstants.device3ColumnsOrder.mapNotNull { map[it] }
} else { }
source 2 -> {
// 2列顺序
ProtocolConstants.device2ColumnsOrder.mapNotNull { map[it] }
}
else -> {
//没有则默认
source
}
} }
} }
fun submitListSortV2(source: List<ShelfModelV2>): List<ShelfModelV2> {
return source.sortedBy { it.slotNo?.toIntOrNull()?:0 }
}
/** /**
* 提交接口list顺序 * 提交接口list顺序