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("")
initRecyclerView()
// 初始化 ScaleManager:注册回调、打开串口、启动接收
initScaleManager()
@@ -176,7 +175,7 @@ class HomeV2Activity : BaseActivity() {
@SuppressLint("NotifyDataSetChanged")
private fun updateUI(data: RespData<*>) {
binding.include?.root?.gone()
binding.include.root.gone()
window?.decorView?.postDelayed({ Loading.dismiss() }, 500)
cabinetInitResult = data.data as? CabinetInitResult
if (cabinetInitResult == null) {
@@ -184,18 +183,27 @@ class HomeV2Activity : BaseActivity() {
loadEmptyView()
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)
App.canteenId = cabinetInitResult!!.canteenId.toString()
var tempList = cabinetInitResult!!.containerGoodsList
App.canteenId = cabinet.canteenId.toString()
var tempList = cabinet.containerGoodsList
if (tempList.isNullOrEmpty()) {
loadEmptyView()
return
}
list.clear()
tempList = GridLayoutTool.initListSortV2(tempList)
tempList = GridLayoutTool.initListSortV2(rows = rows, columns = columns, source = tempList)
list.addAll(tempList)
shelfAdapter.notifyDataSetChanged()
if (binding.rvShelf.adapter == null) {
initRecyclerView(columns)
} else {
shelfAdapter.notifyDataSetChanged()
}
}
private fun showError(message: String) {
@@ -312,19 +320,20 @@ class HomeV2Activity : BaseActivity() {
it.spec = model.spec
it.foodId = model.foodId
it.storeTime = model.storeTime
it.slotStatus = model.slotStatus
}
shelfAdapter.notifyItemChanged(position)
// syncShelfGoodsToServer()
}
private fun initRecyclerView() {
val layoutManager = GridLayoutTool.getLayoutManager(this@HomeV2Activity) ?: return
private fun initRecyclerView(columns: Int) {
val layoutManager = GridLayoutTool.getLayoutManagerV2(this, columns = columns)
binding.rvShelf.let {
it.layoutManager = layoutManager
it.adapter = shelfAdapter
it.itemAnimator.let {
if (it is DefaultItemAnimator) {
it.supportsChangeAnimations = false
it.itemAnimator.let { animator ->
if (animator is DefaultItemAnimator) {
animator.supportsChangeAnimations = false
}
}
}
@@ -361,17 +370,17 @@ class HomeV2Activity : BaseActivity() {
// loadTestData()
}
@SuppressLint("NotifyDataSetChanged")
private fun loadTestData() {
binding.rvShelf.layoutManager = GridLayoutManager(this, 2)
binding.rvShelf.adapter = shelfAdapter
binding.include.root.gone()
list.clear()
var tempList = (1..10).map { i -> ShelfModelV2(slotNo = i.toString()) }
tempList = GridLayoutTool.initListSortV2(tempList)
list.addAll(tempList)
shelfAdapter.notifyDataSetChanged()
}
// @SuppressLint("NotifyDataSetChanged")
// private fun loadTestData() {
// binding.rvShelf.layoutManager = GridLayoutManager(this, 2)
// binding.rvShelf.adapter = shelfAdapter
// binding.include.root.gone()
// list.clear()
// var tempList = (1..10).map { i -> ShelfModelV2(slotNo = i.toString()) }
// tempList = GridLayoutTool.initListSortV2(tempList)
// list.addAll(tempList)
// shelfAdapter.notifyDataSetChanged()
// }
@Subscribe(threadMode = ThreadMode.MAIN)
fun clearEmptyShelf(event: ClearShelfEvent) {
@@ -427,18 +436,18 @@ class HomeV2Activity : BaseActivity() {
/**
* 构建同步请求并提交到服务端
* TODO: 待 ShelfV2Activity 迁移到 RecordItem 后重新实现
*/
private fun syncShelfGoodsToServer() {
if (cabinetInitResult == null) {
return
}
val submitList = GridLayoutTool.submitListSortV2(list)
viewModelV2.syncCabinetData(SyncBody().apply {
// cabinetId = list[0].cabinetId
cabinetId = App.deviceId
temperature = null
humidity = null
goodsList = list
goodsList = submitList
})
}
}
@@ -52,6 +52,7 @@ class ShelfV2Activity : BaseActivity() {
/** itemType=1:净菜包 */
private const val TYPE_CLEAN = 1
/** itemType=2:餐品净菜包 */
private const val TYPE_MEAL = 2
}
@@ -108,7 +109,7 @@ class ShelfV2Activity : BaseActivity() {
val weightG = it.totalWeightG?.toInt() ?: 0
realWeight = weightG
binding.tvFoodWeight.text = if (weightG < 1000) "${weightG}"
else "%.3f千克".format(weightG / 1000.0)
else "%.3f千克".format(weightG / 1000.0)
startTime = System.currentTimeMillis()
}
@@ -137,7 +138,8 @@ class ShelfV2Activity : BaseActivity() {
}
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
}
@@ -168,25 +170,59 @@ class ShelfV2Activity : BaseActivity() {
private fun initButtons() {
binding.ivBack.setOnClickListener { finish() }
binding.btnClearZero.setOnClickListener { clearZero() }
binding.btnClearEmpty.setOnClickListener {
binding.btnClearZero.setOnClickListener {
Loading.show(this@ShelfV2Activity)
clearZero()
window.decorView.postDelayed({ Loading.dismiss() }, 10000)
}
binding.btnClearEmpty.setOnClickListener { v ->
clearZero()
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 {
var shelfModelV2: ShelfModelV2?=null
var shelfModelV2: ShelfModelV2? = null
if (currentType == TYPE_CLEAN) {
val item = cleanList.firstOrNull { it.isSelected }
if (item == null) {
toast("请选择净菜包"); return@clickWithDebounce
}
shelfModelV2 = item.toShelfModelV2(recordItem)
shelfModelV2 = item.toShelfModelV2(recordItem).also {
//1-存放中
it.slotStatus = 1
}
} else {
val item = mealList.firstOrNull { it.isSelected }
if (item == null) {
toast("请选择餐品净菜包"); return@clickWithDebounce
}
shelfModelV2 = item.toShelfModelV2(recordItem)
shelfModelV2 = item.toShelfModelV2(recordItem).also {
//1-存放中
it.slotStatus = 1
}
}
// 将选中结果回传给上层 Activity
val result = Intent().apply {
@@ -311,8 +347,6 @@ class ShelfV2Activity : BaseActivity() {
realWeight = 0
sendCmd(ScaleManager.buildGetStatusCmd())
startTime = System.currentTimeMillis()
Loading.show(this@ShelfV2Activity)
window.decorView.postDelayed({ Loading.dismiss() }, 10000)
}
KeyboardUtil.hideKeyboard(window.decorView)
}
@@ -342,7 +376,7 @@ class ShelfV2Activity : BaseActivity() {
val weight = event.weight
log("格口${recordItem?.slotNo}获取重量:${weight}克,间隔:${intervalTime}ms")
binding.tvFoodWeight.text = if (weight < 1000) "${weight}"
else "%.3f千克".format(weight / 1000.0)
else "%.3f千克".format(weight / 1000.0)
startTime = System.currentTimeMillis()
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显示顺序
*/
@@ -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 }
return if (device3Columns.contains(App.deviceId)) {
// 按全局定义的显示顺序取对应数据,找不到则跳过
ProtocolConstants.device3ColumnsOrder.mapNotNull { map[it] }
} else if (device2Columns.contains(App.deviceId)) {
ProtocolConstants.device2ColumnsOrder.mapNotNull { map[it] }
} else {
source
if (rows != 5) return source
return when (columns) {
3 -> {
// 3列顺序
ProtocolConstants.device3ColumnsOrder.mapNotNull { map[it] }
}
2 -> {
// 2列顺序
ProtocolConstants.device2ColumnsOrder.mapNotNull { map[it] }
}
else -> {
//没有则默认
source
}
}
}
fun submitListSortV2(source: List<ShelfModelV2>): List<ShelfModelV2> {
return source.sortedBy { it.slotNo?.toIntOrNull()?:0 }
}
/**
* 提交接口list顺序