优化调料格子

This commit is contained in:
mazengfei
2026-05-22 10:32:07 +08:00
parent 13390f59dc
commit e8037b12b7
5 changed files with 105 additions and 43 deletions
@@ -1,14 +1,24 @@
package com.shuwei.dish.match.adapter package com.shuwei.dish.match.adapter
import android.content.Context import android.content.Context
import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.text.style.LineHeightSpan
import android.text.style.StyleSpan
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.toColorInt
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
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.ListItemCellBinding import com.shuwei.dish.match.databinding.ListItemCellBinding
import com.shuwei.dish.match.model.GoodsItem import com.shuwei.dish.match.model.GoodsItem
import com.shuwei.dish.match.utils.ext.appendText
import com.shuwei.dish.match.utils.ext.buildSpannableString
import com.shuwei.dish.match.utils.ext.dp import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.roundedOneDecimalPlace
/** /**
* 调料格子列表适配器,使用 list_item_cell 布局展示调料名称与用量 * 调料格子列表适配器,使用 list_item_cell 布局展示调料名称与用量
@@ -24,8 +34,8 @@ class SeasoningAdapter(list: MutableList<GoodsItem>) :
override fun onBindViewHolder(holder: VH, position: Int, item: GoodsItem?) { override fun onBindViewHolder(holder: VH, position: Int, item: GoodsItem?) {
item ?: return item ?: return
// 第4个格子(index=3)使用大尺寸,其余使用标准尺寸 // 第10个格子(index=9)使用大尺寸,其余使用标准尺寸
val isLarge = position == 3 val isLarge = position == 9
holder.binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> { holder.binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
width = if (isLarge) 467.dp else 226.dp width = if (isLarge) 467.dp else 226.dp
height = if (isLarge) 255.dp else 120.dp height = if (isLarge) 255.dp else 120.dp
@@ -34,8 +44,36 @@ class SeasoningAdapter(list: MutableList<GoodsItem>) :
topMargin = 7.dp topMargin = 7.dp
bottomMargin = 8.dp bottomMargin = 8.dp
} }
holder.binding.tvCell.text = TextCellAdapter.getTextSpan(item) holder.binding.tvCell.text = getTextSpan(position, item)
} }
inner class VH(val binding: ListItemCellBinding) : QuickViewHolder(binding.root) inner class VH(val binding: ListItemCellBinding) : QuickViewHolder(binding.root)
fun getTextSpan(position: Int, item: GoodsItem): SpannableStringBuilder {
val endIndex = if (position == 9) 10 else 6
var name = if (item.goodsName.isNullOrBlank()) "未配置" else item.goodsName!!
if (name.length > endIndex) {
name = "${name.substring(0, endIndex)}"
}
return buildSpannableString {
appendText(
name,
ForegroundColorSpan(if (item.goodsName.isNullOrBlank()) "#999999".toColorInt() else "#000000".toColorInt()),
StyleSpan(Typeface.BOLD),
AbsoluteSizeSpan(28, true),
LineHeightSpan { text, start, end, spanstartv, v, fm ->
fm.descent += 10.dp // 增加行间距
}
)
append("\n")
val weight = item.useWeight ?: 0.toDouble()
val weightColor = if (weight == 0.toDouble()) "#999999" else "#00BC71"
appendText(
// "${DecimalFormat("#").format(weight)}g",
"${weight.roundedOneDecimalPlace()}g",
ForegroundColorSpan(weightColor.toColorInt()),
AbsoluteSizeSpan(30, true)
)
}
}
} }
@@ -105,9 +105,6 @@ class TextCellAdapter(var list: MutableList<SeasoningEntity>) :
// } // }
// } // }
fun getTextSpan(item: GoodsItem): SpannableStringBuilder {
return getTextSpan(item.toSeasoningEntity())
}
fun getTextSpan(item: SeasoningEntity): SpannableStringBuilder { fun getTextSpan(item: SeasoningEntity): SpannableStringBuilder {
val endIndex = if (item.sort == 9) 10 else 6 val endIndex = if (item.sort == 9) 10 else 6
var name = if (item.goodsName.isNullOrBlank()) "未配置" else item.goodsName!! var name = if (item.goodsName.isNullOrBlank()) "未配置" else item.goodsName!!
@@ -4,6 +4,7 @@ import androidx.room.Entity
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.shuwei.dish.match.db.BaseEntity import com.shuwei.dish.match.db.BaseEntity
import com.shuwei.dish.match.model.GoodsItem
import com.shuwei.dish.match.utils.DateTimeUtil import com.shuwei.dish.match.utils.DateTimeUtil
import java.time.LocalDateTime import java.time.LocalDateTime
@@ -78,4 +79,19 @@ var isDel: Int = 0,
@Ignore var isClicked: Boolean = false @Ignore var isClicked: Boolean = false
constructor() : this(goodsId = "") // 必需的空构造 constructor() : this(goodsId = "") // 必需的空构造
/** 转换为 GoodsItem,用于 UI 层展示 */
fun toGoodsItem(): GoodsItem = GoodsItem(
goodsId = goodsId,
goodsName = goodsName,
popularName = popularName,
zjmCode = zjmCode,
materId = materId,
materialType = materialType,
useWeight = useWeight,
relateionType = relateionType,
allEdible = allEdible,
goodsOrRelationCode = goodsOrRelationCode,
rawMaterialsType = rawMaterialsType
)
} }
@@ -9,20 +9,16 @@ import android.text.style.LineHeightSpan
import android.text.style.StyleSpan import android.text.style.StyleSpan
import android.util.Log import android.util.Log
import android.util.SparseArray import android.util.SparseArray
import android.util.SparseIntArray
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.graphics.toColorInt import androidx.core.graphics.toColorInt
import androidx.core.view.forEach import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.FlexWrap
import com.shuwei.dish.match.base.BaseActivity import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
import com.shuwei.dish.match.dialog.CommonDialog import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.db.entity.SeasoningEntity import com.shuwei.dish.match.db.entity.SeasoningEntity
import com.shuwei.dish.match.db.entity.ResetReasoningRecord
import com.shuwei.dish.match.model.GoodsItem import com.shuwei.dish.match.model.GoodsItem
import com.shuwei.dish.match.utils.AddressUtil import com.shuwei.dish.match.utils.AddressUtil
import com.shuwei.dish.match.utils.JsonAssetsLoader
import com.shuwei.dish.match.utils.MultiClickDetector import com.shuwei.dish.match.utils.MultiClickDetector
import com.shuwei.dish.match.utils.WeightUtil import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.appendText import com.shuwei.dish.match.utils.ext.appendText
@@ -31,12 +27,10 @@ import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.startActivity import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toast import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible import com.shuwei.dish.match.utils.ext.visible
import com.shuwei.dish.match.R import com.shuwei.dish.match.adapter.SeasoningAdapter
import com.shuwei.dish.match.adapter.TextCellAdapter
import com.shuwei.dish.match.databinding.ActivityDeviceConfigBinding import com.shuwei.dish.match.databinding.ActivityDeviceConfigBinding
import com.shuwei.dish.match.dialog.BottomDialog2 import com.shuwei.dish.match.dialog.BottomDialog2
import com.shuwei.dish.match.utils.SpTool import com.shuwei.dish.match.utils.SpTool
import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.gone import com.shuwei.dish.match.utils.ext.gone
class DeviceConfigActivity : BaseActivity() { class DeviceConfigActivity : BaseActivity() {
@@ -123,7 +117,7 @@ class DeviceConfigActivity : BaseActivity() {
finish() finish()
} }
addWeighListener() addWeighListener()
addGridItemListener() setupRecyclerView()
loadSeasoning() loadSeasoning()
} }
@@ -133,26 +127,34 @@ class DeviceConfigActivity : BaseActivity() {
getWeight = { address, state, weight -> getWeight = { address, state, weight ->
Log.d(TAG, "addWeighListener: address=$address,stat=$state,weight=$weight") Log.d(TAG, "addWeighListener: address=$address,stat=$state,weight=$weight")
weightArray.put(address, weight) weightArray.put(address, weight)
val item = seasoningItems.firstOrNull { address == addressArray[it.sort] } // val item = seasoningItems.firstOrNull { address == addressArray[it.sort] }
item?.let { // item?.let {
it.useWeight = weight.toDouble() // it.useWeight = weight.toDouble()
// updateGridData(it) //// updateGridData(it)
} // }
Log.d(TAG, "addWeighListener: update-----------------------") Log.d(TAG, "addWeighListener: update-----------------------")
}) })
} }
private val seasoningItems = MutableList(12) { GoodsItem() }
private var seasoningItems = mutableListOf<SeasoningEntity>() private val seasoningAdapter by lazy {
private fun addGridItemListener() { SeasoningAdapter(seasoningItems).apply {
binding.include.root.forEach { child -> setOnItemClickListener { adapter, _, position ->
child.clickWithDebounce { val item = adapter.getItem(position) ?: return@setOnItemClickListener
val sort = child.tag.toString().toInt() clickGridItem(position,item.toSeasoningEntity())
val entity = seasoningItems.firstOrNull { it.sort == sort } ?: SeasoningEntity()
clickGridItem(sort, entity)
} }
} }
} }
private fun setupRecyclerView() {
// 初始化 FlexboxLayoutManager,横向排列(FlexDirection.ROW
val flexboxLayoutManager = FlexboxLayoutManager(this).apply {
flexDirection = FlexDirection.ROW
flexWrap = FlexWrap.WRAP
}
binding.rvSeasoning.layoutManager = flexboxLayoutManager
binding.rvSeasoning.adapter = seasoningAdapter
}
val detector = MultiClickDetector(targetCount = 10, intervalMs = 800) val detector = MultiClickDetector(targetCount = 10, intervalMs = 800)
private fun defaultDataSettingDialog() { private fun defaultDataSettingDialog() {
@@ -173,17 +175,16 @@ class DeviceConfigActivity : BaseActivity() {
} }
private fun loadSeasoning() { private fun loadSeasoning() {
appViewModel.loadSeasoning { appViewModel.loadSeasoning { list ->
seasoningItems.clear() seasoningItems.clear()
seasoningItems.addAll(it) // 将 SeasoningEntity 转为 GoodsItem 后提交给 adapter
// initConfigData() val goodsItems = list.map { it.toGoodsItem() }
// setGridData(seasoningItems) seasoningAdapter.submitList(goodsItems)
} }
} }
private fun clickGridItem(sort: Int, entity: SeasoningEntity) { private fun clickGridItem(sort: Int, entity: SeasoningEntity) {
val currentAddress = AddressUtil.getWeighAddressArray().get(sort) val currentAddress = AddressUtil.getWeighAddressArray().get(sort)
// val seasoningEntity = list.first{it.sort == sort}
BottomDialog2( BottomDialog2(
weighIndex = sort, weighIndex = sort,
weighAddress = currentAddress, weighAddress = currentAddress,
@@ -194,10 +195,21 @@ class DeviceConfigActivity : BaseActivity() {
entity.materialType = 3 entity.materialType = 3
entity.sort = sort entity.sort = sort
saveSeasoning(entity) { saveSeasoning(entity) {
val tag = sort.toString() // 更新 adapter 中对应位置的数据
val gridLayout = binding.include.root val goodsItem = GoodsItem(
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag) goodsId = entity.goodsId,
TextCellAdapter.loadLayout(frameLayout, entity) goodsName = entity.goodsName,
popularName = entity.popularName,
zjmCode = entity.zjmCode,
materId = entity.materId,
materialType = entity.materialType,
useWeight = entity.useWeight,
relateionType = entity.relateionType,
allEdible = entity.allEdible,
goodsOrRelationCode = entity.goodsOrRelationCode,
rawMaterialsType = entity.rawMaterialsType
)
seasoningAdapter.set(sort, goodsItem)
} }
} }
} }
@@ -128,11 +128,10 @@
</LinearLayout> </LinearLayout>
<include <androidx.recyclerview.widget.RecyclerView
android:id="@+id/include" android:id="@+id/rvSeasoning"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="725dp" />
layout="@layout/layout_grid"/>
</LinearLayout> </LinearLayout>