feat(pack): 重构净菜包装页面并集成食材搜索功能

- 替换重量识别功能为食材选择搜索功能
- 新增 FoodSearchV2Activity 页面实现食材搜索选择
- 添加 InboundIngredientV2Adapter 适配器展示食材列表
- 创建 MaterialTypeTool 工具类统一处理食材类型文本
- 更新 CleanPackActivity 集成食材搜索返回逻辑
- 修改布局文件适配新的食材选择流程
- 调整环境配置中的API地址映射关系
- 优化 RecyclerView 显示和交互逻辑
- 移除原有的重量识别相关界面元素和代码
- 更新提交参数收集逻辑支持新食材数据结构
This commit is contained in:
2026-06-03 16:05:19 +08:00
parent ad9291243f
commit 01ff7241cd
16 changed files with 525 additions and 73 deletions
+1
View File
@@ -158,6 +158,7 @@
android:launchMode="singleTask"
android:screenOrientation="landscape"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity android:name="com.shuwei.dish.match.ui.FoodSearchV2Activity" />
<receiver
android:name=".utils.BootReceiver"
@@ -14,6 +14,7 @@ import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.roundedOneDecimalPlace
import com.shuwei.dish.match.utils.ext.visible
import androidx.core.graphics.toColorInt
import com.shuwei.dish.match.ui.MaterialTypeTool
class FoodMaterialAdapter(list: MutableList<GoodsItem>) :
BaseQuickAdapter<GoodsItem, FoodMaterialAdapter.VH>(list) {
@@ -44,7 +45,9 @@ class FoodMaterialAdapter(list: MutableList<GoodsItem>) :
//}
val showGoodsCode = (data.materCode ?: "").ifBlank { "-" }
tvGoodsCode.text = "溯源码:$showGoodsCode"
tvDishType.text = if (data.materialType == 1) "主辅材:主材" else if (data.materialType == 2) "主辅材:辅材" else ""
val materialText = MaterialTypeTool.getMaterialText(data.materialType)
tvDishType.text = "主辅材:$materialText"
//if (data.materialType == 1) "主辅材:主材" else if (data.materialType == 2) "主辅材:辅材" else ""
tvDishWeight.text =
if (data.useWeight == null || data.useWeight == 0.toDouble()) "" else "${data.useWeight!!.roundedOneDecimalPlace()}"
tvDishWeight.setTextColor(
@@ -57,11 +60,11 @@ class FoodMaterialAdapter(list: MutableList<GoodsItem>) :
ivOperateIcon.run {
if (data.isSamplingPage) gone() else visible()
}
ivClearIcon.visible()
ivClearIcon.setImageResource(
if (data.isOriginalData) R.drawable.ic_dish_clear
else R.drawable.ic_delete
)
// ivClearIcon.visible()
// ivClearIcon.setImageResource(
// if (data.isOriginalData) R.drawable.ic_dish_clear
// else R.drawable.ic_delete
// )
// isOriginalData 时根据是否有重量信息控制图标颜色:无重量染灰色,有重量恢复原色
if (data.isOriginalData) {
val hasWeight = data.useWeight != null && data.useWeight != 0.0
@@ -0,0 +1,40 @@
package com.shuwei.dish.match.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.shuwei.dish.match.databinding.ListItemInboundIngredient2Binding
import com.shuwei.dish.match.model.NutCleanInboundIngredientVO
import com.shuwei.dish.match.utils.ext.formatDecimal
/**
* 已入库净菜食材列表适配器 V2
*/
class InboundIngredientV2Adapter(list: MutableList<NutCleanInboundIngredientVO>) :
BaseQuickAdapter<NutCleanInboundIngredientVO, InboundIngredientV2Adapter.VH>(list) {
inner class VH(var binding: ListItemInboundIngredient2Binding) :
QuickViewHolder(binding.root)
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
val binding = ListItemInboundIngredient2Binding.inflate(
LayoutInflater.from(context), parent, false
)
return VH(binding)
}
override fun onBindViewHolder(holder: VH, position: Int, item: NutCleanInboundIngredientVO?) {
item ?: return
holder.binding.run {
tvIngredientName.text = item.ingredientName ?: "-"
val traceCode = item.traceCode.takeUnless { it.isNullOrBlank() } ?: "-"
tvTraceCode.text = "溯源码:$traceCode"
val stock = item.currentStock.takeUnless { it.isNullOrBlank() } ?: "0"
tvStock.text = "库存:${stock.formatDecimal()}kg"
}
}
}
@@ -10,6 +10,7 @@ import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.shuwei.dish.match.R
import com.shuwei.dish.match.databinding.ListItemTaskDetailBinding
import com.shuwei.dish.match.model.NutComboTaskItemDetail
import com.shuwei.dish.match.ui.MaterialTypeTool
import com.shuwei.dish.match.utils.ext.formatDecimal
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.visible
@@ -38,19 +39,19 @@ class TaskDetailAdapter(list: MutableList<NutComboTaskItemDetail>) :
position: Int,
item: NutComboTaskItemDetail?
) {
item?:return
item ?: return
holder.binding.apply {
// Set ingredient name
tvIngredientName.text = item.ingredientName
// 食材类别
val classText = when (item.ingredientClass) {
1 -> "主材"
2 -> "辅材"
3 -> "调料"
else -> "-"
}
tvIngredientClass.text = classText
// val classText = when (item.ingredientClass) {
// 1 -> "主材"
// 2 -> "辅材"
// 3 -> "调料"
// else -> "-"
// }
tvIngredientClass.text = MaterialTypeTool.getMaterialText(item.ingredientClass ?: 0)
val unit = item.unit ?: "g"
tvPerPortionQty.text = "每份用量:${item.perPortionQty.formatDecimal()}${unit}"
@@ -66,7 +67,7 @@ class TaskDetailAdapter(list: MutableList<NutComboTaskItemDetail>) :
// tvTotalQty.text = "合计用量:${item?.totalQty.formatDecimal()}${unit}"
tvTraceCode.visible()
tvTraceCode.text = "溯源码:${(item.traceCode ?:"").ifBlank { "-" }}"
tvTraceCode.text = "溯源码:${(item.traceCode ?: "").ifBlank { "-" }}"
// val hasWeight = item.actualQty.isNullOrBlank().not()
// ivClearIcon.imageTintList = if (hasWeight) null else ColorStateList.valueOf("#BFBFBF".toColorInt())
@@ -8,14 +8,16 @@ package com.shuwei.dish.match.base
enum class DeviceRole { MASTER, SLAVE }
object GlobalData {
var appBaseUrl: String = TEST_BASE_URL
var appBaseUrl: String = LOCAL_BASE_URL
/**
* 具体业务 BaseUrl
*/
// const val TEST_BASE_URL = "http://192.168.1.201:14801"
const val TEST_BASE_URL = "http://192.168.10.101:24801"
const val UAT_BASE_URL = "https://dev.yixiong-tech.com:8083"
// const val LOCAL_BASE_URL = "http://192.168.1.201:14801"
const val LOCAL_BASE_URL = "http://192.168.10.101:24801"
const val TEST_BASE_URL = "https://dev.yixiong-tech.com:8081"
// const val TEST_BASE_URL = "https://dev.yixiong-tech.com:8083"
const val PROD_BASE_URL = "https://api.dm.yixiong-tech.com:8443"
/**
* 设备id
@@ -40,8 +40,8 @@ class EnvSwitchDialog(
return@setPositiveButtonInterceptable false
}
val newUrl = when (contentBinding.rgEnv.checkedRadioButtonId) {
contentBinding.rbTest.id -> GlobalData.TEST_BASE_URL
contentBinding.rbUat.id -> GlobalData.UAT_BASE_URL
contentBinding.rbTest.id -> GlobalData.LOCAL_BASE_URL
contentBinding.rbUat.id -> GlobalData.TEST_BASE_URL
contentBinding.rbProd.id -> GlobalData.PROD_BASE_URL
else -> return@setPositiveButtonInterceptable false
}
@@ -54,8 +54,8 @@ class EnvSwitchDialog(
init {
// 根据当前 appBaseUrl 预选对应 RadioButton
when (GlobalData.appBaseUrl) {
GlobalData.TEST_BASE_URL -> contentBinding.rbTest.isChecked = true
GlobalData.UAT_BASE_URL -> contentBinding.rbUat.isChecked = true
GlobalData.LOCAL_BASE_URL -> contentBinding.rbTest.isChecked = true
GlobalData.TEST_BASE_URL -> contentBinding.rbUat.isChecked = true
GlobalData.PROD_BASE_URL -> contentBinding.rbProd.isChecked = true
}
}
@@ -76,7 +76,9 @@ data class NutFoodComposition(
var ingredientName: String?,
var traceCode: String?,
var amount: Double?,
var isMain: Int?
var isMain: Int?,
//1-主材、2-辅材、3-调料
var mainText: String?=null
) : Parcelable
/**
@@ -312,6 +312,8 @@ class NetViewModelV2(
*/
fun getInboundIngredientOptionsWithCallback(
keyword: String? = null,
pageNum: Int = 1,
pageSize: Int = 20,
onLoading: () -> Unit = {},
onResult: (UiState<List<NutCleanInboundIngredientVO>?>) -> Unit
) {
@@ -1,6 +1,8 @@
package com.shuwei.dish.match.ui
import android.content.Intent
import android.os.Bundle
import androidx.core.content.IntentCompat
import androidx.recyclerview.widget.GridLayoutManager
import com.shuwei.dish.match.adapter.FormFieldAdapter
import com.shuwei.dish.match.base.BaseActivity
@@ -9,6 +11,7 @@ import com.shuwei.dish.match.databinding.ActivityCleanPackBinding
import com.shuwei.dish.match.model.DictType
import com.shuwei.dish.match.model.FieldType
import com.shuwei.dish.match.model.FormField
import com.shuwei.dish.match.model.NutCleanInboundIngredientVO
import com.shuwei.dish.match.model.NutFoodOptionVO
import com.shuwei.dish.match.net.NetViewModelV2
import com.shuwei.dish.match.net.UiState
@@ -18,6 +21,7 @@ import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.roundedOneDecimalPlace
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible
import kotlinx.coroutines.Job
@@ -113,10 +117,12 @@ class CleanPackActivity : BaseActivity() {
hideKeyboard()
if (!validateFields()) return@setOnClickListener
when (packType) {
TYPE_CLEAN -> submitCleanPackage()
TYPE_MEAL -> submitMealPackage()
}
// when (packType) {
// TYPE_CLEAN -> submitCleanPackage()
// TYPE_MEAL -> submitMealPackage()
// }
submitCleanPackage()
}
binding.ivClearWeight.clickWithDebounce {
@@ -126,10 +132,23 @@ class CleanPackActivity : BaseActivity() {
}
binding.flSearchBar.clickWithDebounce {
val launchIntent = Intent(this, FoodSearchV2Activity::class.java)
startActivity(launchIntent) { data ->
data?:return@startActivity
IntentCompat.getParcelableExtra<NutCleanInboundIngredientVO>(
data,
FoodSearchV2Activity.INGREDIENT_ITEM,
NutCleanInboundIngredientVO::class.java
)?.let { food ->
this@CleanPackActivity.currentFood = food
binding.tvFoodName.text = food.ingredientName
}
}
}
}
private var currentFood: NutCleanInboundIngredientVO? = null
/**
* 初始化单品净菜包装表单字段
* 对应接口 NutSupCleanPackageDTO
@@ -608,8 +627,8 @@ class CleanPackActivity : BaseActivity() {
* 收集字段提交值,根据 apiKey / extraApiKeys 规则汇总
* @return 提交参数 Mapkey 为接口参数名,value 为提交值
*/
private fun collectSubmitValues(): MutableMap<String, String> {
val params = mutableMapOf<String, String>()
private fun collectSubmitValues(): MutableMap<String, String?> {
val params = mutableMapOf<String, String?>()
for (field in fields) {
if (field.hidden) continue
// 跳过 CHILDREN 类型,暂不处理
@@ -637,6 +656,15 @@ class CleanPackActivity : BaseActivity() {
toast("未识别到重量")
return
}
if (currentFood == null || currentFood!!.ingredientName.isNullOrBlank() || currentFood!!.traceCode.isNullOrBlank()) {
toast("食材信息错误")
return
}
val food = currentFood!!
params["traceCode"] = food.traceCode
params["cleanInboundId"] = food.id.toString()
params["cleanName"] = food.ingredientName
params["weightPerUnit"] = currentWeight.toString()
viewModelV2.addCleanPackage(params) { state, msg ->
if (state.not()) {
@@ -0,0 +1,204 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter4.util.setOnDebouncedItemClick
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.InboundIngredientV2Adapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.ActivityFoodSearchV2Binding
import com.shuwei.dish.match.databinding.LayoutEmptyViewBinding
import com.shuwei.dish.match.model.NutCleanInboundIngredientVO
import com.shuwei.dish.match.net.NetViewModelV2
import com.shuwei.dish.match.net.UiState
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible
import kotlinx.coroutines.launch
/**
* 食材搜索页面 V2,使用 NetViewModelV2 的回调接口查询已入库净菜食材
*/
class FoodSearchV2Activity : BaseActivity() {
companion object {
const val INGREDIENT_ITEM = "ingredientItem"
const val INGREDIENT_NAME = "ingredientName"
const val PAGE_SIZE = 30
}
private lateinit var binding: ActivityFoodSearchV2Binding
private val viewModelV2 by lazy { NetViewModelV2() }
private val list = mutableListOf<NutCleanInboundIngredientVO>()
private val recordAdapter by lazy {
InboundIngredientV2Adapter(list).apply {
isStateViewEnable = true
setOnDebouncedItemClick { _, _, position ->
val item = list.getOrNull(position) ?: return@setOnDebouncedItemClick
setResult(RESULT_OK, Intent().apply {
putExtra(INGREDIENT_ITEM, item)
})
finish()
}
}
}
private var ingredientName: String? = null
private var currentPage = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityFoodSearchV2Binding.inflate(layoutInflater)
setContentView(binding.root)
setHeaderBackground()
ingredientName = intent.getStringExtra(INGREDIENT_NAME)
binding.etInputIngredient.setText(ingredientName)
setTitleBar(titleBarAction = {
it.visible()
}, titleAction = {
it.text = "食材搜索"
}, rightIconAction = {
it.gone()
})
binding.rvIngredientList.let {
it.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
it.adapter = recordAdapter
}
addViewListener()
// 若有传入食材名称,自动触发搜索
queryIngredientList(ingredientName)
}
private fun addViewListener() {
binding.ivIngredientSearch.setOnClickListener {
getInputAndSearch()
}
binding.refreshLayout.setEnableRefresh(true)
binding.refreshLayout.setEnableLoadMore(false)
binding.refreshLayout.run {
setOnRefreshListener {
currentPage = 1
val input = binding.etInputIngredient.text.toString().trim()
queryIngredientList(input)
}
setOnLoadMoreListener {
val input = binding.etInputIngredient.text.toString().trim()
queryIngredientList(input)
}
}
binding.root.setOnClickListener {
hideKeyboard()
}
binding.etInputIngredient.run {
setOnEditorActionListener { _, actionId, _ ->
if (actionId == android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH) {
getInputAndSearch()
true
} else {
false
}
}
addTextChangedListener(onTextChanged = { text, _, _, _ ->
if (text.isNullOrBlank()) {
currentPage = 1
queryIngredientList()
}
})
}
}
private fun getInputAndSearch() {
val input = binding.etInputIngredient.text.toString().trim()
if (input.isBlank()) {
toast("请输入食材名称")
binding.refreshLayout.finishRefresh()
return
}
queryIngredientList(input)
}
/**
* 查询已入库净菜食材列表
*/
private fun queryIngredientList(keyword: String? = null) {
hideKeyboard()
showLoading()
viewModelV2.getInboundIngredientOptionsWithCallback(
keyword = keyword,
pageNum = currentPage,
pageSize = PAGE_SIZE,
onLoading = {},
onResult = { state ->
lifecycleScope.launch {
when (state) {
is UiState.Success -> handleSearchResult(state.data)
is UiState.Error -> {
delayDismissLoading()
if (currentPage == 1) {
binding.refreshLayout.finishRefresh()
} else {
binding.refreshLayout.finishLoadMore()
}
toast(state.msg)
loadEmptyView()
}
else -> {}
}
}
})
}
/**
* 处理搜索结果,填充列表或展示空视图
*/
@SuppressLint("NotifyDataSetChanged")
private fun handleSearchResult(records: List<NutCleanInboundIngredientVO>?) {
delayDismissLoading()
if (currentPage == 1 && records.isNullOrEmpty()) {
loadEmptyView()
return
}
list.clear()
list.addAll(records!!)
recordAdapter.notifyDataSetChanged()
val isLoadMore = records.size >= PAGE_SIZE
binding.refreshLayout.setEnableLoadMore(isLoadMore)
if (isLoadMore) {
currentPage++
binding.refreshLayout.finishLoadMore()
}
else {
binding.refreshLayout.finishLoadMoreWithNoMoreData()
}
}
private var emptyViewBinding: LayoutEmptyViewBinding? = null
@SuppressLint("NotifyDataSetChanged")
private fun loadEmptyView() {
list.clear()
recordAdapter.notifyDataSetChanged()
if (emptyViewBinding == null) {
emptyViewBinding = LayoutEmptyViewBinding.inflate(
LayoutInflater.from(this), binding.rvIngredientList, false
)
}
emptyViewBinding!!.tvContent.text = "暂无数据"
emptyViewBinding!!.tvSubContent.text = "可以尝试换个名称重新搜索"
recordAdapter.stateView = emptyViewBinding!!.root
binding.refreshLayout.run {
setEnableRefresh(false)
setEnableLoadMore(false)
}
}
}
@@ -0,0 +1,12 @@
package com.shuwei.dish.match.ui
object MaterialTypeTool {
fun getMaterialText(type: Int) = when (type) {
1 -> "主料"
2 -> "辅料"
3 -> "调料"
else -> ""
}
}
@@ -274,7 +274,10 @@ class PackActivity : BaseActivity() {
//包装餐品名称
params["mealName"] = food.foodName
//包装日期
params["packageDate"] = DateTimeUtil.formatDateTime(dateTime = LocalDateTime.now(), pattern = DateTimeUtil.YYYY_MM_DD)
params["packageDate"] = DateTimeUtil.formatDateTime(
dateTime = LocalDateTime.now(),
pattern = DateTimeUtil.YYYY_MM_DD
)
// //操作类型
// params["opType"] = "设备自动"
@@ -285,7 +288,8 @@ class PackActivity : BaseActivity() {
ingredientName = it.goodsName,
traceCode = it.materCode,
amount = it.useWeight,
isMain = if (it.materialType == 1) 1 else 0
isMain = it.materialType,
mainText = MaterialTypeTool.getMaterialText(it.materialType)
)
}.toMutableList()
@@ -433,7 +437,7 @@ class PackActivity : BaseActivity() {
GoodsItem().apply {
goodsId = comp.materId?.toString() ?: ""
goodsName = comp.ingredientName ?: ""
materialType = if (comp.isMain == 1) 1 else 2
materialType = comp.isMain ?: 0
useWeight = 0.0
isOriginalData = true
isSetFinished = false
@@ -647,30 +651,30 @@ class PackActivity : BaseActivity() {
private fun initRecyclerView() {
initFormList()
binding.rvFormList.let {
it.layoutManager = GridLayoutManager(this, 4, GridLayoutManager.VERTICAL, false)
it.layoutManager = GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
it.adapter = formAdapter
}
binding.rvMaterialList.let {
it.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// 仅 isNewDishType=true 的 item 显示侧滑删除菜单(必须在 setAdapter 之前调用)
it.setSwipeMenuCreator { _, rightMenu, position ->
if (list.getOrNull(position)?.isNewDishType == true) {
rightMenu.addMenuItem(buildDeleteMenuItem())
}
}
// 点击侧滑菜单项:先关闭菜单,再弹窗确认删除
it.setOnItemMenuClickListener { menuBridge, position ->
menuBridge.closeMenu()
val item = list.getOrNull(position) ?: return@setOnItemMenuClickListener
deleteRemindDialog("删除确认", "确定删除食材「${item.goodsName}」吗?") {
removeFood(position)
}
}
// item 点击事件
it.setOnItemClickListener { _, position ->
materialAdapter.onItemClick?.invoke(position)
}
// it.setSwipeMenuCreator { _, rightMenu, position ->
// if (list.getOrNull(position)?.isNewDishType == true) {
// rightMenu.addMenuItem(buildDeleteMenuItem())
// }
// }
// // 点击侧滑菜单项:先关闭菜单,再弹窗确认删除
// it.setOnItemMenuClickListener { menuBridge, position ->
// menuBridge.closeMenu()
// val item = list.getOrNull(position) ?: return@setOnItemMenuClickListener
// deleteRemindDialog("删除确认", "确定删除食材「${item.goodsName}」吗?") {
// removeFood(position)
// }
// }
// // item 点击事件
// it.setOnItemClickListener { _, position ->
// materialAdapter.onItemClick?.invoke(position)
// }
handleRvTouchHideKeyboard()
it.adapter = materialAdapter
}
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
tools:background="@drawable/bg_other_page">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="30dp"
android:background="@drawable/shape_white_30_corners"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/etInputIngredient"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_marginStart="28dp"
android:layout_weight="1"
android:autofillHints=""
android:background="@color/white"
android:gravity="center"
android:hint="@string/dish_search_hint2"
android:paddingStart="3dp"
android:paddingEnd="3dp"
android:inputType="text"
android:imeOptions="actionSearch"
android:textColor="@color/black333"
android:textColorHint="@color/gray_c8"
android:textSize="40sp"
tools:ignore="TextFields" />
<ImageView
android:id="@+id/ivIngredientSearch"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:src="@drawable/ic_search_gray"
tools:ignore="ContentDescription" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:layout_marginBottom="30dp"
android:layout_weight="1"
android:background="@drawable/shape_white_30_corners"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="40dp"
android:layout_marginBottom="40dp"
android:text="食材列表"
android:textColor="@color/black666"
android:textSize="28sp" />
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.scwang.smart.refresh.header.ClassicsHeader
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvIngredientList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="20dp"
android:overScrollMode="never"
tools:listitem="@layout/list_item_inbound_ingredient" />
<com.scwang.smart.refresh.footer.ClassicsFooter
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
</LinearLayout>
</LinearLayout>
+7 -20
View File
@@ -11,7 +11,8 @@
android:id="@+id/llSearchBar"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="30dp"
android:layout_marginHorizontal="30dp"
android:layout_marginVertical="20dp"
android:background="@drawable/shape_white_30_corners"
android:gravity="center_vertical"
android:orientation="horizontal">
@@ -77,7 +78,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="160dp"
android:layout_height="140dp"
android:gravity="center_vertical"
android:orientation="horizontal">
@@ -123,7 +124,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="30dp"
android:layout_marginBottom="10dp"
android:text="在下方列表中选择食材计重"
android:textColor="@color/black999"
android:textSize="26sp" />
@@ -147,27 +148,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginVertical="30dp"
android:layout_marginVertical="20dp"
android:layout_marginStart="20dp"
android:padding="10dp"
android:text="@string/dish_composition"
android:textColor="@color/black666"
android:textSize="28sp" />
<!-- 重量显示已注释,重量识别功能整体已移除 -->
<!--
<TextView
android:id="@+id/tvShowWeight"
android:layout_width="wrap_content"
android:layout_height="80dp"
android:layout_gravity="end|center_vertical"
android:paddingHorizontal="30dp"
android:gravity="center_vertical"
android:maxLines="1"
android:textColor="@color/black666"
android:textSize="28sp" />
-->
<TextView
android:id="@+id/btnGetTraceCode"
android:layout_width="wrap_content"
@@ -188,8 +175,8 @@
android:layout_height="1dp" />
</FrameLayout>
<com.yanzhenjie.recyclerview.SwipeRecyclerView
<!-- com.yanzhenjie.recyclerview.SwipeRecyclerView-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvMaterialList"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -77,7 +77,8 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
tools:ignore="ContentDescription"
android:visibility="gone"/>
<TextView
android:id="@+id/tvDishWeight"
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/clBlock"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_margin="15dp"
android:background="@drawable/shape_white_12_corners"
android:foreground="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineH"
android:layout_width="1dp"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.7" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineV"
android:layout_width="match_parent"
android:layout_height="1dp"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@+id/tvIngredientName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:maxLength="20"
android:maxLines="1"
android:textColor="@color/black333"
android:textSize="28sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@id/guidelineV"
app:layout_constraintEnd_toStartOf="@id/guidelineH"
app:layout_constraintStart_toStartOf="parent"
tools:text="土豆" />
<TextView
android:id="@+id/tvStock"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="end|center_vertical"
android:textColor="@color/black999"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="@id/tvIngredientName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/guidelineH"
app:layout_constraintTop_toTopOf="@id/tvIngredientName"
tools:text="库存:12.5kg" />
<TextView
android:id="@+id/tvTraceCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:textColor="@color/dish_green"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/guidelineV"
tools:text="溯源码:TR20260101001" />
</androidx.constraintlayout.widget.ConstraintLayout>