refactor: 提取净材种类弹窗为工具类并统一各页面选择逻辑

- 新增 RawMaterialsDialogUtils,包含 showRawMaterialsDialog、
  buildSingleChoiceChipGroup、buildMockGoodsList 三个顶层函数
- FoodAdapter/list_item_food 新增净材种类选中结果展示
- VectorCollectionFragment、FoodRecognizeActivity、FoodSearchDialog
  的食材点击均改为弹出净材种类单选弹窗后再确认选中
- FoodSearchDialog 空布局补充点击加载测试数据
- setting_border 新增圆角
This commit is contained in:
2026-05-11 12:07:06 +08:00
parent 63911fe432
commit ec4c3f1232
7 changed files with 278 additions and 211 deletions
@@ -48,6 +48,14 @@ class FoodAdapter(list: MutableList<GoodsItem>) :
it.text = foodScoreText
}
}
if (item.rawMaterialsType.isNullOrBlank()) {
holder.binding.tvRawMaterialsType.gone()
} else {
holder.binding.tvRawMaterialsType.let {
it.visible()
it.text = item.rawMaterialsType
}
}
}
override fun onCreateViewHolder(
@@ -18,6 +18,7 @@ import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter4.util.setOnDebouncedItemClick
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.FoodAdapter
@@ -28,6 +29,8 @@ import com.shuwei.dish.match.dialog.SeasoningSelectDialog.Companion.PAGE_SIZE
import com.shuwei.dish.match.entity.GoodsItem
import com.shuwei.dish.match.net.UiState
import com.shuwei.dish.match.utils.KeyboardUtil
import com.shuwei.dish.match.utils.buildMockGoodsList
import com.shuwei.dish.match.utils.showRawMaterialsDialog
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
import com.shuwei.dish.match.utils.ext.toast
import kotlinx.coroutines.launch
@@ -50,36 +53,25 @@ class FoodSearchDialog(
private val binding = DialogFoodSearchBinding.inflate(LayoutInflater.from(activity))
private val list = mutableListOf<GoodsItem>()
// .apply {
// 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 = "洋葱丁"))
// add(GoodsItem(goodsId = "200012", goodsName = "A"))
// add(GoodsItem(goodsId = "200013", goodsName = "B"))
// add(GoodsItem(goodsId = "200014", goodsName = "C"))
// add(GoodsItem(goodsId = "200015", goodsName = "D"))
// add(GoodsItem(goodsId = "200016", goodsName = "E"))
// add(GoodsItem(goodsId = "200017", goodsName = "F"))
// add(GoodsItem(goodsId = "200018", goodsName = "G"))
// add(GoodsItem(goodsId = "200019", goodsName = "H"))
// }
private val adapter = FoodAdapter(list).apply {
isStateViewEnable = true
setOnItemClickListener { _, _, position ->
list[position].isClicked = true
notifyItemChanged(position)
binding.root.postDelayed({
onItemSelected(list[position])
dismiss()
}, 300)
setOnDebouncedItemClick { _, _, position ->
val item = list[position]
// 弹出净材种类单选弹窗,确认后再回调并关闭弹窗
showRawMaterialsDialog(
context = activity,
types = item.rawMaterialsTypes,
checkedType = item.rawMaterialsType
) { selectedType ->
item.rawMaterialsType = selectedType
item.isClicked = true
notifyItemChanged(position)
binding.root.postDelayed({
onItemSelected(item)
dismiss()
}, 300)
}
}
}
@@ -241,6 +233,11 @@ class FoodSearchDialog(
}
binding.recyclerView.layoutManager = GridLayoutManager(activity, 2, GridLayoutManager.VERTICAL, false)
if (pageNo == 1) list.clear()
// 将接口返回的 rawMaterialsType(全部种类)移存到 rawMaterialsTypes,供弹窗使用
records.forEach {
it.rawMaterialsTypes = it.rawMaterialsType
it.rawMaterialsType = null
}
list.addAll(records)
adapter.notifyDataSetChanged()
val isLoadMoreEnable = records.size >= PAGE_SIZE
@@ -269,16 +266,19 @@ class FoodSearchDialog(
false
)
}
emptyViewBinding!!.tvContent.text = "暂无数据"
emptyViewBinding!!.tvSubContent.text = "未查询到食材信息,请联系管理员添加"
emptyViewBinding!!.root.layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
)
binding.recyclerView.layoutManager = LinearLayoutManager(activity)
binding.recyclerView.post {
emptyViewBinding!!.root.minimumHeight = binding.recyclerView.height
adapter.stateView = emptyViewBinding!!.root
emptyViewBinding?.let {
it.tvContent.text = "暂无数据"
it.tvSubContent.text = "未查询到食材信息,请联系管理员添加"
it.root.setOnClickListener { loadGoodsList(buildMockGoodsList().toMutableList()) }
it.root.layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
)
binding.recyclerView.layoutManager = LinearLayoutManager(activity)
binding.recyclerView.post {
it.root.minimumHeight = binding.recyclerView.height
adapter.stateView = it.root
}
}
} catch (e: Exception) {
e.printStackTrace()
@@ -25,6 +25,7 @@ import com.shuwei.dish.match.net.UiState
import com.shuwei.dish.match.objbox.FoodModule
import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.showRawMaterialsDialog
import kotlinx.coroutines.launch
/**
@@ -122,12 +123,21 @@ class FoodRecognizeActivity : BaseActivity() {
private val adapter = FoodAdapter(list).apply {
setOnItemClickListener { _, _, position ->
list.forEachIndexed { i, item -> item.isClicked = (i == position) }
// 点击选择时记录当前秤重量
list[position].useWeight = currentWeight
notifyDataSetChanged()
selectedPosition = position
binding.tvSelectedFood.text = list[position].goodsName ?: "-"
val item = list[position]
// 弹出净材种类单选弹窗,确认后再选中该食材
showRawMaterialsDialog(
context = this@FoodRecognizeActivity,
types = item.rawMaterialsTypes,
checkedType = item.rawMaterialsType
) { selectedType ->
item.rawMaterialsType = selectedType
list.forEachIndexed { i, it -> it.isClicked = (i == position) }
// 点击选择时记录当前秤重量
item.useWeight = currentWeight
notifyDataSetChanged()
selectedPosition = position
binding.tvSelectedFood.text = item.goodsName ?: "-"
}
}
}
@@ -260,6 +270,9 @@ class FoodRecognizeActivity : BaseActivity() {
goodsList.forEach {
val food = nameScoreMap[it.goodsName]
val foodScore = ((1 - (food?.score ?: 0.0)) * 10000).toInt()
// 将接口返回的 rawMaterialsType(全部种类)移存到 rawMaterialsTypes,供弹窗使用
it.rawMaterialsTypes = it.rawMaterialsType
it.rawMaterialsType = null
list.add(it.also { it.foodScore = foodScore })
}
adapter.notifyDataSetChanged()
@@ -3,7 +3,6 @@ package com.shuwei.dish.match.ui.fragment
import android.annotation.SuppressLint
import android.content.Intent
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.net.Uri
import android.util.Log
@@ -12,10 +11,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import androidx.core.view.doOnLayout
import androidx.core.view.updateLayoutParams
import androidx.lifecycle.lifecycleScope
@@ -32,7 +28,6 @@ import com.shuwei.dish.match.base.BaseFragment
import com.shuwei.dish.match.databinding.FragmentVectorCollectionBinding
import com.shuwei.dish.match.databinding.LayoutCameraPreviewBinding
import com.shuwei.dish.match.databinding.LayoutEmptyViewBinding
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.dialog.Loading
import com.shuwei.dish.match.entity.FoodCollectionBean
import com.shuwei.dish.match.entity.GoodsItem
@@ -48,6 +43,9 @@ import com.shuwei.dish.match.utils.Debouncer
import com.shuwei.dish.match.utils.ImageUploader
import com.shuwei.dish.match.utils.ImageUtil
import com.shuwei.dish.match.utils.LogSaveUtil
import com.shuwei.dish.match.utils.buildSingleChoiceChipGroup
import com.shuwei.dish.match.utils.buildMockGoodsList
import com.shuwei.dish.match.utils.showRawMaterialsDialog
import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.gone
@@ -81,9 +79,27 @@ class VectorCollectionFragment : BaseFragment<FragmentVectorCollectionBinding>()
isStateViewEnable = true
setOnDebouncedItemClick { _, _, position ->
val item = searchList[position]
val types = item.rawMaterialsTypes
// 弹出净材种类单选弹窗
showRawMaterialsDialog(item, position, types)
showRawMaterialsDialog(
context = requireContext(),
types = item.rawMaterialsTypes,
checkedType = item.rawMaterialsType
) { selectedType ->
// 清空其他已选项的状态
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
notifyDataSetChanged()
}
}
}
}
@@ -424,148 +440,6 @@ class VectorCollectionFragment : BaseFragment<FragmentVectorCollectionBinding>()
}
}
/**
* 构造用于效果测试的食材假数据
* TODO: 联调完成后删除
*/
private fun buildMockGoodsList(): List<GoodsItem> = 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 = "豆芽"),
)
/**
* 弹出净材种类单选弹窗
* @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 {
// 构建单选 ChipGroup 作为自定义内容
val chipGroup = buildSingleChoiceChipGroup(typeList, item.rawMaterialsType)
dialog.addContentView(chipGroup) { tvContent ->
tvContent.gone()
}
dialog.setPositiveButtonInterceptable("确认") {
val checkedId = chipGroup.checkedChipId
if (checkedId == View.NO_ID) {
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()
}
/**
* 构建单选样式的 ChipGroup
* @param typeList 选项文本列表,列表中每一项作为一个 Chip 的文字
* @param checkedType 默认选中项的文本,与 typeList 中元素相等的 Chip 会被勾选;为空则无默认选中
* @return 配置完成的 ChipGroup,每个 Chip 的 id 即为其在 typeList 中的下标
*/
private fun buildSingleChoiceChipGroup(
typeList: List<String>,
checkedType: String?
): ChipGroup {
return ChipGroup(requireContext()).apply {
isSingleSelection = true
isSelectionRequired = false
setPadding(5.dp, 40.dp, 5.dp, 40.dp)
chipSpacingVertical = 10.dp
chipSpacingHorizontal = 20.dp
typeList.forEachIndexed { index, typeName ->
val chip = Chip(requireContext()).apply {
id = index
text = typeName
textSize = 22f
isCheckable = true
chipStartPadding = 20.dp.toFloat()
chipEndPadding = 20.dp.toFloat()
chipMinHeight = (textSize + 15.dp * 2).toFloat()
// 选中/未选中态背景色:主题绿 / 浅灰
chipBackgroundColor = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked)
),
intArrayOf(
ContextCompat.getColor(requireContext(), R.color.dish_green),
ContextCompat.getColor(requireContext(), R.color.gray_eb)
)
)
// 选中/未选中态文字色:白 / 深灰
setTextColor(
ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked)
),
intArrayOf(
ContextCompat.getColor(requireContext(), R.color.white),
ContextCompat.getColor(requireContext(), R.color.black333)
)
)
)
// 隐藏默认的左侧勾选图标,让填充色作为唯一选中反馈
isCheckedIconVisible = false
// 去除描边
chipStrokeWidth = 0f
// 若当前项已有选中值则默认勾选对应选项
isChecked = (typeName == checkedType)
}
addView(chip)
}
}
}
var clickIndex = -1
@SuppressLint("NotifyDataSetChanged")
@@ -0,0 +1,151 @@
package com.shuwei.dish.match.utils
import android.content.Context
import android.content.res.ColorStateList
import android.view.View
import androidx.core.content.ContextCompat
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import com.shuwei.dish.match.R
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.entity.GoodsItem
import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.toast
/**
* 构造用于效果测试的食材假数据
* TODO: 联调完成后删除
*/
fun buildMockGoodsList(): List<GoodsItem> = 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 = "豆芽"),
)
/**
* 弹出净材种类单选弹窗
* 确认选中后通过 onConfirmed 回调返回选中的种类文本,业务逻辑由调用方自行处理;
* 无净材数据时展示提示文字,点击确认直接关闭弹窗。
*
* @param context 上下文
* @param types 净材种类字符串(逗号分隔),为空时提示无数据
* @param checkedType 弹窗打开时的默认选中项(与 types 中元素对比),null 表示无默认选中
* @param onConfirmed 用户选中并确认后的回调,参数为选中的净材种类文本
*/
fun showRawMaterialsDialog(
context: Context,
types: String?,
checkedType: String?,
onConfirmed: (selectedType: String) -> Unit
) {
val typeList = types?.split(",")?.map { it.trim() }?.filter { it.isNotEmpty() } ?: emptyList()
val dialog = CommonDialog(context)
.setTitle("选择净材种类")
.setNegativeButton("取消")
if (typeList.isEmpty()) {
// 无净材数据时仅展示提示文字
dialog.setContent("无净材数据")
.setPositiveButton("确认") {}
} else {
// 构建单选 ChipGroup 作为自定义内容
val chipGroup = buildSingleChoiceChipGroup(context, typeList, checkedType)
dialog.addContentView(chipGroup) { tvContent -> tvContent.gone() }
dialog.setPositiveButtonInterceptable("确认") {
val checkedId = chipGroup.checkedChipId
if (checkedId == View.NO_ID) {
context.toast("请选择净材种类")
// 返回 false 阻止弹窗关闭
return@setPositiveButtonInterceptable false
}
onConfirmed(typeList[checkedId])
true
}
}
dialog.show()
}
/**
* 构建单选样式的 ChipGroup
*
* @param context 上下文
* @param typeList 选项文本列表,每一项作为一个 Chip 的文字
* @param checkedType 默认选中项的文本,与 typeList 中元素相等的 Chip 会被勾选;为空则无默认选中
* @return 配置完成的 ChipGroup,每个 Chip 的 id 即为其在 typeList 中的下标
*/
fun buildSingleChoiceChipGroup(
context: Context,
typeList: List<String>,
checkedType: String?
): ChipGroup {
return ChipGroup(context).apply {
isSingleSelection = true
isSelectionRequired = false
setPadding(5.dp, 40.dp, 5.dp, 40.dp)
chipSpacingVertical = 10.dp
chipSpacingHorizontal = 20.dp
typeList.forEachIndexed { index, typeName ->
val chip = Chip(context).apply {
id = index
text = typeName
textSize = 22f
isCheckable = true
chipStartPadding = 20.dp.toFloat()
chipEndPadding = 20.dp.toFloat()
chipMinHeight = (textSize + 15.dp * 2).toFloat()
// 选中/未选中态背景色:主题绿 / 浅灰
chipBackgroundColor = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked)
),
intArrayOf(
ContextCompat.getColor(context, R.color.dish_green),
ContextCompat.getColor(context, R.color.gray_eb)
)
)
// 选中/未选中态文字色:白 / 深灰
setTextColor(
ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked)
),
intArrayOf(
ContextCompat.getColor(context, R.color.white),
ContextCompat.getColor(context, R.color.black333)
)
)
)
// 隐藏默认的左侧勾选图标,让填充色作为唯一选中反馈
isCheckedIconVisible = false
// 去除描边
chipStrokeWidth = 0f
// 若当前项已有选中值则默认勾选对应选项
isChecked = (typeName == checkedType)
}
addView(chip)
}
}
}
@@ -3,4 +3,5 @@
android:shape="rectangle">
<solid android:color="#FFF4FAFF"/>
<stroke android:width="2dp" android:color="@color/white"/>
<corners android:radius="8dp"/>
</shape>
+38 -18
View File
@@ -1,35 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<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:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="100dp"
android:layout_margin="15dp">
<TextView
android:id="@+id/tvGoodsInfo"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_height="match_parent"
android:background="@drawable/shape_white_12_corners"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingHorizontal="5dp"
android:textColor="@color/black666"
android:textSize="30sp"
android:paddingHorizontal="5dp"
android:gravity="center"
android:layout_margin="15dp"
tools:text="椒盐"
android:maxLines="1"
tools:text="椒盐" />
<TextView
android:id="@+id/tvRawMaterialsType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:background="@drawable/shape_white_12_corners"/>
android:gravity="center"
android:maxLines="1"
android:textColor="@color/black999"
android:textSize="18sp"
android:visibility="gone"
android:layout_marginBottom="5dp"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/tvFoodScore"
app:layout_constraintStart_toStartOf="parent"
tools:text="切丝" />
<TextView
android:id="@+id/tvFoodScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black666"
android:textSize="16sp"
android:layout_marginBottom="20dp"
android:layout_gravity="bottom|center_horizontal"
tools:text="100%"
android:maxLines="1"
android:ellipsize="end"
android:visibility="gone"/>
android:maxLines="1"
android:textColor="@color/black666"
android:layout_marginStart="10dp"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="@id/tvRawMaterialsType"
app:layout_constraintBottom_toBottomOf="@id/tvRawMaterialsType"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tvRawMaterialsType"
tools:text="100%" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>