feat(fragment): 新增净材种类选择功能及相关数据结构支持

- 新增 rawMaterialsType 字段至 GoodsItem、CookFoodGoodsEntity、SeasoningEntity,DB 升级至 v12
- VectorCollectionFragment 重构食材搜索,点击食材弹出净材种类单选弹窗
- CommonDialog 新增 addContentView 和可拦截确认按钮(setPositiveButtonInterceptable)能力
- Food3Adapter 和 list_item_food3.xml 支持显示已选净材种类副标签
This commit is contained in:
2026-05-09 18:10:07 +08:00
parent a9663a21f0
commit ef13aa8307
11 changed files with 268 additions and 53 deletions
@@ -2,6 +2,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.View
import android.view.ViewGroup import android.view.ViewGroup
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
@@ -24,6 +25,15 @@ class Food3Adapter(list: MutableList<GoodsItem>) :
text = item.goodsName text = item.goodsName
isChecked = item.isClicked isChecked = item.isClicked
} }
// 显示当前选中的净材种类,无数据时隐藏
holder.binding.tvRawMaterialsType.run {
if (item.rawMaterialsType.isNullOrEmpty()) {
visibility = View.GONE
} else {
visibility = View.VISIBLE
text = item.rawMaterialsType
}
}
} }
override fun onCreateViewHolder( override fun onCreateViewHolder(
@@ -25,7 +25,7 @@ import com.shuwei.dish.match.entity.SeasoningSlotEntity
CookFoodGoodsEntity::class, CookFoodGoodsEntity::class,
SeasoningSlotEntity::class, SeasoningSlotEntity::class,
], ],
version = 11, version = 12,
exportSchema = true exportSchema = true
) )
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
@@ -240,6 +240,14 @@ val MIGRATION_10_11 = MigrationImpl(10, 11) { db ->
db.execSQL("ALTER TABLE dm_seasoning ADD COLUMN goodsCode TEXT DEFAULT ''") db.execSQL("ALTER TABLE dm_seasoning ADD COLUMN goodsCode TEXT DEFAULT ''")
} }
/**
* 版本11→12:为 dm_cook_food_goods 和 dm_seasoning 表新增 rawMaterialsType(净材种类)字段
*/
val MIGRATION_11_12 = MigrationImpl(11, 12) { db ->
db.execSQL("ALTER TABLE dm_cook_food_goods ADD COLUMN rawMaterialsType TEXT DEFAULT NULL")
db.execSQL("ALTER TABLE dm_seasoning ADD COLUMN rawMaterialsType TEXT DEFAULT NULL")
}
class DatabaseProvider(private val context: Context) { class DatabaseProvider(private val context: Context) {
// 单例模式确保全局唯一实例‌ // 单例模式确保全局唯一实例‌
val instance: AppDatabase by lazy { val instance: AppDatabase by lazy {
@@ -262,6 +270,7 @@ class DatabaseProvider(private val context: Context) {
.addMigrations(MIGRATION_8_9) .addMigrations(MIGRATION_8_9)
.addMigrations(MIGRATION_9_10) .addMigrations(MIGRATION_9_10)
.addMigrations(MIGRATION_10_11) .addMigrations(MIGRATION_10_11)
.addMigrations(MIGRATION_11_12)
.build() .build()
} }
} }
@@ -7,6 +7,7 @@ import android.os.Bundle
import android.view.View import android.view.View
import android.view.Window import android.view.Window
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import com.shuwei.dish.match.base.DeviceRole import com.shuwei.dish.match.base.DeviceRole
import com.shuwei.dish.match.base.GlobalData import com.shuwei.dish.match.base.GlobalData
@@ -26,9 +27,14 @@ open class CommonDialog(
private var positiveText = "确认" private var positiveText = "确认"
private var neutralText: String? = null private var neutralText: String? = null
private var negativeClick: (() -> Unit)? = null private var negativeClick: (() -> Unit)? = null
private var positiveClick: (() -> Unit)? = null // 返回 true 时关闭弹窗,返回 false 时保持弹窗显示(用于校验不通过的场景)
private var positiveClick: (() -> Boolean)? = null
private var neutralClick: (() -> Unit)? = null private var neutralClick: (() -> Unit)? = null
private var dismissCallback: (() -> Unit)? = null private var dismissCallback: (() -> Unit)? = null
// 待添加到 llContent 的自定义 View,在 onCreate 后挂载
private var pendingContentView: View? = null
// pendingContentView 非空时对 tvContent 的灵活控制回调(可调整可见性、间距等)
private var tvContentConfigurator: ((TextView) -> Unit)? = null
/** 设置标题,为空时隐藏 */ /** 设置标题,为空时隐藏 */
fun setTitle(text: String): CommonDialog = apply { titleText = text } fun setTitle(text: String): CommonDialog = apply { titleText = text }
@@ -42,8 +48,17 @@ open class CommonDialog(
negativeClick = onClick negativeClick = onClick
} }
/** 设置右侧确认按钮文字及点击回调(3按钮模式下对应底部按钮) */ /** 设置右侧确认按钮文字及点击回调(3按钮模式下对应底部按钮),点击后自动关闭弹窗 */
fun setPositiveButton(text: String, onClick: (() -> Unit)? = null): CommonDialog = apply { fun setPositiveButton(text: String, onClick: (() -> Unit)? = null): CommonDialog = apply {
positiveText = text
positiveClick = onClick?.let { { it(); true } }
}
/**
* 设置右侧确认按钮文字及可拦截的点击回调
* 回调返回 true 时关闭弹窗,返回 false 时保持弹窗显示(用于校验不通过的场景)
*/
fun setPositiveButtonInterceptable(text: String, onClick: () -> Boolean): CommonDialog = apply {
positiveText = text positiveText = text
positiveClick = onClick positiveClick = onClick
} }
@@ -59,6 +74,16 @@ open class CommonDialog(
dismissCallback = callback dismissCallback = callback
} }
/**
* 向弹窗自定义内容区域添加 View,调用后 llContent 自动显示
* @param view 要嵌入的自定义布局(如单选列表)
* @param tvContentConfig 可选回调,用于在 pendingContentView 非空时灵活控制 tvContent 的可见性及间距等属性
*/
fun addContentView(view: View, tvContentConfig: ((TextView) -> Unit)? = null): CommonDialog = apply {
pendingContentView = view
tvContentConfigurator = tvContentConfig
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE) requestWindowFeature(Window.FEATURE_NO_TITLE)
@@ -88,8 +113,8 @@ open class CommonDialog(
dismiss() dismiss()
} }
binding.btnRight.setOnClickListener { binding.btnRight.setOnClickListener {
positiveClick?.invoke() // 回调返回 false 时阻止关闭,null 或 true 时正常关闭
dismiss() if (positiveClick?.invoke() != false) dismiss()
} }
// 3按钮点击事件(negativeClick/positiveClick 与2按钮模式共用) // 3按钮点击事件(negativeClick/positiveClick 与2按钮模式共用)
@@ -102,11 +127,17 @@ open class CommonDialog(
dismiss() dismiss()
} }
binding.btnBottom.setOnClickListener { binding.btnBottom.setOnClickListener {
positiveClick?.invoke() if (positiveClick?.invoke() != false) dismiss()
dismiss()
} }
setOnDismissListener { dismissCallback?.invoke() } setOnDismissListener { dismissCallback?.invoke() }
// 挂载自定义内容 View,并执行 tvContent 的灵活控制回调
pendingContentView?.let {
binding.llContent.addView(it)
binding.llContent.visibility = View.VISIBLE
tvContentConfigurator?.invoke(binding.tvContent)
}
} }
override fun show() { override fun show() {
@@ -69,6 +69,9 @@ class CookFoodGoodsEntity(
/** 物料编码 */ /** 物料编码 */
var goodsCode: String? = "", var goodsCode: String? = "",
/** 净材种类 */
var rawMaterialsType: String? = null,
var isDel: Int = 0, var isDel: Int = 0,
var createTime: String = DateTimeUtil.formatDateTime(LocalDateTime.now()) var createTime: String = DateTimeUtil.formatDateTime(LocalDateTime.now())
) : BaseEntity, Serializable { ) : BaseEntity, Serializable {
@@ -88,6 +91,7 @@ class CookFoodGoodsEntity(
useWeight = useWeight, useWeight = useWeight,
relateionType = relateionType, relateionType = relateionType,
allEdible = allEdible, allEdible = allEdible,
goodsOrRelationCode = goodsOrRelationCode goodsOrRelationCode = goodsOrRelationCode,
rawMaterialsType = rawMaterialsType
) )
} }
@@ -31,7 +31,11 @@ data class GoodsItem(
// true-原始数据,false-非原始数据(识图新增) // true-原始数据,false-非原始数据(识图新增)
var isOriginalData: Boolean = true, var isOriginalData: Boolean = true,
// 识图匹配分数,-1 表示不显示 // 识图匹配分数,-1 表示不显示
var foodScore: Int = -1 var foodScore: Int = -1,
// 净材种类(当前选中值)
var rawMaterialsType: String? = null,
// 净材种类候选列表(临时字段,逗号分隔,不持久化)
var rawMaterialsTypes: String? = null
) : Serializable { ) : Serializable {
/** /**
@@ -53,7 +57,8 @@ data class GoodsItem(
useWeight = useWeight, useWeight = useWeight,
relateionType = relateionType, relateionType = relateionType,
allEdible = allEdible, allEdible = allEdible,
goodsOrRelationCode = goodsOrRelationCode goodsOrRelationCode = goodsOrRelationCode,
rawMaterialsType = rawMaterialsType
) )
/** /**
@@ -69,6 +74,7 @@ data class GoodsItem(
materialType = materialType, materialType = materialType,
relateionType = relateionType, relateionType = relateionType,
allEdible = allEdible, allEdible = allEdible,
goodsOrRelationCode = goodsOrRelationCode goodsOrRelationCode = goodsOrRelationCode,
rawMaterialsType = rawMaterialsType
) )
} }
@@ -61,6 +61,9 @@ data class SeasoningEntity(
/** 物料编码 */ /** 物料编码 */
var goodsCode: String? = "", var goodsCode: String? = "",
/** 净材种类 */
var rawMaterialsType: String? = null,
var sort: Int = 9999, var sort: Int = 9999,
/** /**
* isDel表示数据是否已删除,1-已删除,为无效数据,0-正常使用,有效数据 * isDel表示数据是否已删除,1-已删除,为无效数据,0-正常使用,有效数据
@@ -11,6 +11,9 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.view.Gravity
import android.widget.RadioButton
import android.widget.RadioGroup
import androidx.camera.view.PreviewView import androidx.camera.view.PreviewView
import androidx.core.view.doOnLayout import androidx.core.view.doOnLayout
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
@@ -25,6 +28,7 @@ import com.shuwei.dish.match.adapter.Food3Adapter
import com.shuwei.dish.match.base.BaseFragment import com.shuwei.dish.match.base.BaseFragment
import com.shuwei.dish.match.databinding.FragmentVectorCollectionBinding import com.shuwei.dish.match.databinding.FragmentVectorCollectionBinding
import com.shuwei.dish.match.databinding.LayoutCameraPreviewBinding import com.shuwei.dish.match.databinding.LayoutCameraPreviewBinding
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.dialog.Loading import com.shuwei.dish.match.dialog.Loading
import com.shuwei.dish.match.entity.FoodCollectionBean import com.shuwei.dish.match.entity.FoodCollectionBean
import com.shuwei.dish.match.entity.GoodsItem import com.shuwei.dish.match.entity.GoodsItem
@@ -42,9 +46,11 @@ import com.shuwei.dish.match.utils.ImageUtil
import com.shuwei.dish.match.utils.LogSaveUtil import com.shuwei.dish.match.utils.LogSaveUtil
import com.shuwei.dish.match.utils.ext.clickWithDebounce import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.dp import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.toast import com.shuwei.dish.match.utils.ext.toast
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import androidx.core.content.withStyledAttributes
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
class VectorCollectionFragment : BaseFragment<FragmentVectorCollectionBinding>() { class VectorCollectionFragment : BaseFragment<FragmentVectorCollectionBinding>() {
@@ -63,30 +69,15 @@ class VectorCollectionFragment : BaseFragment<FragmentVectorCollectionBinding>()
} }
} }
private val searchList = mutableListOf<GoodsItem>().apply { private val searchList = mutableListOf<GoodsItem>()
add(GoodsItem(goodsId = "200001", goodsName = "土豆丝"))
add(GoodsItem(goodsId = "200002", goodsName = "土豆片"))
add(GoodsItem(goodsId = "200003", goodsName = "土豆丁"))
add(GoodsItem(goodsId = "200004", goodsName = "胡萝卜丝"))
add(GoodsItem(goodsId = "200005", goodsName = "胡萝卜片"))
add(GoodsItem(goodsId = "200006", goodsName = "胡萝卜丁"))
add(GoodsItem(goodsId = "200007", goodsName = "黄瓜丝"))
add(GoodsItem(goodsId = "200008", goodsName = "黄瓜片"))
add(GoodsItem(goodsId = "200009", goodsName = "黄瓜丁"))
add(GoodsItem(goodsId = "200010", goodsName = "洋葱丝"))
add(GoodsItem(goodsId = "200011", goodsName = "洋葱丁"))
}
private var checkedItem: GoodsItem? = null private var checkedItem: GoodsItem? = null
private val searchAdapter by lazy { private val searchAdapter by lazy {
Food3Adapter(searchList).apply { Food3Adapter(searchList).apply {
setOnItemClickListener { adapter, view, position -> setOnItemClickListener { _, _, position ->
searchList.forEachIndexed { index, item -> item.isClicked = index == position } val item = searchList[position]
checkedItem = searchList[position] val types = item.rawMaterialsTypes
notifyDataSetChanged() // 弹出净材种类单选弹窗
checkedItem?.let { showRawMaterialsDialog(item, position, types)
selectedFoodId = it.goodsId
selectedFoodName = it.goodsName
}
} }
} }
} }
@@ -340,14 +331,144 @@ class VectorCollectionFragment : BaseFragment<FragmentVectorCollectionBinding>()
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
fun searchFood() { fun searchFood() {
debouncer.debounce { debouncer.debounce {
searchByFoodName(binding.editFoodName.text.toString()) { val keyword = binding.editFoodName.text.toString().trim()
// searchFoodList.clear() // 通过 NetViewModel 查询净材数据(goodsType=0 食材)
// searchFoodList.addAll(it) currentActivity.netViewModel.queryGoodsList(
// searchFoodAdapter.notifyDataSetChanged() goodsType = "0",
goodsName = keyword.ifEmpty { null }
)
// 监听查询结果(一次性收集,避免重复订阅)
lifecycleScope.launch {
currentActivity.netViewModel.goodsListState.collect { state ->
when (state) {
is UiState.Success -> {
var list: List<GoodsItem> = state.data ?: emptyList()
// TODO: 接口暂无数据时使用假数据进行效果测试,联调完成后删除
if (list.isEmpty()) {
list = mutableListOf(
GoodsItem(goodsId = "1", goodsName = "土豆", rawMaterialsType = "土豆丝,土豆条,土豆片,土豆丁"),
GoodsItem(goodsId = "2", goodsName = "胡萝卜", rawMaterialsType = "胡萝卜丝,胡萝卜片,胡萝卜丁"),
GoodsItem(goodsId = "3", goodsName = "黄瓜", rawMaterialsType = "黄瓜丝,黄瓜片,黄瓜丁,黄瓜块"),
GoodsItem(goodsId = "4", goodsName = "洋葱", rawMaterialsType = "洋葱丝,洋葱丁,洋葱圈"),
GoodsItem(goodsId = "5", goodsName = "白菜", rawMaterialsType = "白菜丝,白菜块,白菜叶"),
GoodsItem(goodsId = "6", goodsName = "豆腐", rawMaterialsType = "豆腐块,豆腐丁"),
GoodsItem(goodsId = "7", goodsName = "猪肉", rawMaterialsType = "猪肉丝,猪肉片,猪肉丁,猪肉块"),
GoodsItem(goodsId = "8", goodsName = "鸡胸肉", rawMaterialsType = "鸡胸肉丝,鸡胸肉片,鸡胸肉丁"),
GoodsItem(goodsId = "9", goodsName = "牛肉", rawMaterialsType = "牛肉丝,牛肉片,牛肉块"),
GoodsItem(goodsId = "10", goodsName = "虾仁", rawMaterialsType = "整虾仁,切段虾仁"),
GoodsItem(goodsId = "11", goodsName = "茄子", rawMaterialsType = "茄子丝,茄子片,茄子块,茄子条"),
GoodsItem(goodsId = "12", goodsName = "青椒", rawMaterialsType = "青椒丝,青椒片,青椒块"),
GoodsItem(goodsId = "13", goodsName = "西红柿", rawMaterialsType = "西红柿片,西红柿块,西红柿丁"),
GoodsItem(goodsId = "14", goodsName = "芹菜", rawMaterialsType = "芹菜段,芹菜丝"),
GoodsItem(goodsId = "15", goodsName = "莲藕", rawMaterialsType = "莲藕片,莲藕丁,莲藕丝"),
// 以下5条 rawMaterialsType 为空,测试无净材数据场景
GoodsItem(goodsId = "16", goodsName = "菠菜"),
GoodsItem(goodsId = "17", goodsName = "生菜"),
GoodsItem(goodsId = "18", goodsName = "香菇"),
GoodsItem(goodsId = "19", goodsName = "木耳"),
GoodsItem(goodsId = "20", goodsName = "豆芽"),
)
}
// 将 rawMaterialsType 转存到 rawMaterialsTypes,并清空 rawMaterialsType
list.forEach { item ->
item.rawMaterialsTypes = item.rawMaterialsType
item.rawMaterialsType = null
}
searchList.clear()
searchList.addAll(list)
searchAdapter.notifyDataSetChanged()
}
else -> Unit
}
}
} }
} }
} }
/**
* 弹出净材种类单选弹窗
* @param item 当前点击的食材项
* @param position 在 searchList 中的位置
* @param types 净材种类字符串(逗号分隔),为空时提示无数据
*/
@SuppressLint("NotifyDataSetChanged")
private fun showRawMaterialsDialog(item: GoodsItem, position: Int, types: String?) {
val typeList = types?.split(",")?.map { it.trim() }?.filter { it.isNotEmpty() } ?: emptyList()
val dialog = CommonDialog(requireContext())
.setTitle("选择净材种类")
.setNegativeButton("取消")
if (typeList.isEmpty()) {
// 无净材数据时仅展示提示文字
dialog.setContent("无净材数据")
.setPositiveButton("确认") {}
} else {
// 构建单选 RadioGroup 作为自定义内容
val radioGroup = RadioGroup(requireContext()).apply {
orientation = RadioGroup.VERTICAL
// RadioGroup 本身居中,子项 wrap_content 宽度,整体图标+文字自然居中
gravity = Gravity.CENTER_HORIZONTAL
typeList.forEachIndexed { index, typeName ->
val rb = RadioButton(requireContext()).apply {
id = index
text = typeName
textSize = 26f
layoutParams = RadioGroup.LayoutParams(
RadioGroup.LayoutParams.WRAP_CONTENT,
RadioGroup.LayoutParams.WRAP_CONTENT
)
setPadding(30.dp, 15.dp, 30.dp, 15.dp)
// 移除默认点击水波纹背景,改用 foreground 实现 selectableItemBackground 效果
setBackgroundResource(0)
val attrs = intArrayOf(android.R.attr.selectableItemBackground)
context.withStyledAttributes(null, attrs) {
foreground = getDrawable(0)
}
// 若当前项已有选中值则默认勾选对应选项
if (typeName == item.rawMaterialsType) isChecked = true
// 通过 InsetDrawable 在 buttonDrawable 右侧追加 80dp 间距,实现图标与文字的间距控制
buttonDrawable?.let { orig ->
buttonDrawable = android.graphics.drawable.InsetDrawable(
orig, 30.dp, 0, 30.dp, 0
)
}
}
addView(rb)
}
}
dialog.addContentView(radioGroup) { tvContent ->
tvContent.gone()
}
dialog.setPositiveButtonInterceptable("确认") {
val checkedId = radioGroup.checkedRadioButtonId
if (checkedId == -1) {
toast("请选择净材种类")
// 返回 false 阻止弹窗关闭
return@setPositiveButtonInterceptable false
}
val selectedType = typeList[checkedId]
// 清空其他已选项的状态
searchList.forEachIndexed { index, it ->
if (index != position) {
it.isClicked = false
it.rawMaterialsType = null
}
}
// 设置当前选中项
item.isClicked = true
item.rawMaterialsType = selectedType
checkedItem = item
selectedFoodId = item.goodsId
selectedFoodName = item.goodsName
searchAdapter.notifyDataSetChanged()
true
}
}
dialog.show()
}
var clickIndex = -1 var clickIndex = -1
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
@@ -391,7 +512,6 @@ class VectorCollectionFragment : BaseFragment<FragmentVectorCollectionBinding>()
LogSaveUtil.saveLogFile(msg) LogSaveUtil.saveLogFile(msg)
} }
private fun searchByFoodName(name: String, block: (String) -> Unit) {}
private fun hideWaitingDialog() { private fun hideWaitingDialog() {
currentActivity.dismissLoading() currentActivity.dismissLoading()
} }
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- 绿色圆角背景 + 白色垃圾桶图标,替代红色的 ic_delete_red.png --> <?xml version="1.0" encoding="utf-8"?>
<!-- 绿色圆形背景 + 白色垃圾桶图标,替代红色的 ic_delete_red.png -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 绿色圆角背景 --> <!-- 绿色圆角背景 -->
@@ -6,10 +7,10 @@
<shape android:shape="oval"> <shape android:shape="oval">
<solid android:color="#00BC71" /> <solid android:color="#00BC71" />
<padding <padding
android:bottom="5dp" android:bottom="8dp"
android:left="5dp" android:left="8dp"
android:right="5dp" android:right="8dp"
android:top="5dp" /> android:top="8dp" />
</shape> </shape>
</item> </item>
+10
View File
@@ -37,6 +37,16 @@
android:textSize="26sp" android:textSize="26sp"
tools:text="这是弹窗的内容信息,请确认"/> tools:text="这是弹窗的内容信息,请确认"/>
<!-- 自定义内容区域,默认隐藏,通过 CommonDialog.addContentView 动态填充 -->
<LinearLayout
android:id="@+id/llContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"
android:orientation="vertical"
android:visibility="gone" />
<!-- 分割线 --> <!-- 分割线 -->
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -18,6 +18,7 @@
android:layout_gravity="center" android:layout_gravity="center"
android:text="点击分格配置调料" android:text="点击分格配置调料"
android:includeFontPadding="false" android:includeFontPadding="false"
android:textStyle="bold"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="20sp" /> android:textSize="20sp" />
</FrameLayout> </FrameLayout>
+31 -11
View File
@@ -1,18 +1,38 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tvFoodName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="100dp" android:layout_height="100dp"
android:background="@drawable/bg_item_search"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:layout_marginHorizontal="14dp" android:layout_marginHorizontal="14dp"
android:layout_marginVertical="14dp" android:layout_marginVertical="14dp"
android:background="@drawable/bg_item_search"
android:paddingHorizontal="15dp" android:paddingHorizontal="15dp"
android:textAlignment="center" android:paddingVertical="10dp">
android:textColor="@color/color_item_search"
android:textSize="30sp" <!-- 食材名称,选中状态通过 CheckedTextView 的 checked 驱动背景/文字色变化 -->
android:textStyle="bold" <CheckedTextView
tools:text="土豆丝" /> android:id="@+id/tvFoodName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:textAlignment="center"
android:textColor="@color/color_item_search"
android:textSize="28sp"
android:textStyle="bold"
tools:text="土豆丝" />
<!-- 当前选中的净材种类,小字显示,无数据时隐藏 -->
<TextView
android:id="@+id/tvRawMaterialsType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center|bottom"
android:textColor="@color/black999"
android:textSize="18sp"
android:visibility="gone"
tools:text="切丝" />
</FrameLayout>