feat(shelf): 添加净菜毛菜搜索和分类选择功能

- 新增 tvFoodType TextView 显示食品分类
- 将搜索框可见性从 gone 改为 visible
- 添加 FoodItem 和 FoodType 数据模型
- 添加 SearchFoodRequest 请求模型
- 在 ApiServiceV3 中新增 searchFood 接口
- 在 NetViewModelV3 中新增 searchFood 方法
- 修改 PutSlotRequest 模型字段为可空类型并添加 vegTypeId
- 更新 HomeV3Activity 中行列计算逻辑
- 缩短商品数据同步间隔时间
- 修改 InitActivity 中的基础URL配置
- 将 PendingInboundAdapter 适配器改为使用 FoodItem 类型
- 在 ShelfV3Activity 中实现净菜分类选择对话框功能
- 添加 ChipSelectDialog 自定义对话框组件
- 添加 chip 相关的颜色资源文件
- 实现搜索功能替换原有的待入库查询逻辑
This commit is contained in:
2026-06-26 14:57:07 +08:00
parent 84634f843d
commit 0e0c2fe47b
15 changed files with 331 additions and 30 deletions
@@ -0,0 +1,100 @@
package com.shuwei.intelligent.shelves.dialog
import android.app.Dialog
import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import com.google.android.material.chip.Chip
import com.shuwei.intelligent.shelves.R
import com.shuwei.intelligent.shelves.base.BaseDialog
import com.shuwei.intelligent.shelves.databinding.DialogChipSelectBinding
import com.shuwei.intelligent.shelves.utils.ext.dp
import com.shuwei.intelligent.shelves.utils.ext.hideKeyboard
/**
* 带ChipGroup选择的弹窗,支持传入选项列表,回调返回选中索引
*/
class ChipSelectDialog(context: Context) : Dialog(context, R.style.DialogTheme) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DialogChipSelectBinding.inflate(LayoutInflater.from(context))
setContentView(binding.root)
setCancelable(false)
setCanceledOnTouchOutside(false)
window?.apply {
//setLayout(defWidth, defHeight)
setBackgroundDrawable(ColorDrawable())
setGravity(Gravity.CENTER)
}
binding.root.setOnClickListener { it.hideKeyboard() }
initView()
}
private lateinit var binding: DialogChipSelectBinding
/** 弹窗标题 */
var dialogTitle: String? = null
/** 选项列表 */
var items: List<String?> = emptyList()
/** 选中回调,返回选中的索引,取消时不触发 */
var onItemSelected: ((Int) -> Unit)? = null
/** 当前选中的索引,默认-1表示未选中 */
private var selectedIndex: Int = -1
fun initView() {
binding.btnCancel.setOnClickListener {
dismiss()
}
binding.btnConfirm.setOnClickListener {
if (selectedIndex >= 0) {
onItemSelected?.invoke(selectedIndex)
}
dismiss()
}
}
override fun show() {
super.show()
binding.tvDialogTitle.text = dialogTitle
setupChips()
}
/**
* 动态创建Chip并添加到ChipGroup中
*/
private fun setupChips() {
binding.chipGroup.removeAllViews()
selectedIndex = -1
items.forEachIndexed { index, label ->
val chip = Chip(context).apply {
text = label
isCheckable = true
isCheckedIconVisible = false
textSize = 20f
chipStartPadding = 15.dp.toFloat()
chipEndPadding = 15.dp.toFloat()
textStartPadding = 8.dp.toFloat()
textEndPadding = 8.dp.toFloat()
chipMinHeight = 50.dp.toFloat()
setTextColor(resources.getColorStateList(R.color.chip_text_color, null))
chipBackgroundColor = resources.getColorStateList(R.color.chip_bg_color, null)
chipStrokeWidth = 1f
chipStrokeColor = resources.getColorStateList(R.color.chip_stroke_color, null)
setOnClickListener {
selectedIndex = index
}
}
binding.chipGroup.addView(chip)
}
}
}
@@ -151,8 +151,10 @@ class HomeV3Activity : BaseActivity() {
// val columns = if (ProtocolConstants.device3Columns.contains(App.deviceId)) 3 else 2 // val columns = if (ProtocolConstants.device3Columns.contains(App.deviceId)) 3 else 2
// val rows = if (slots.size % columns == 0) slots.size / columns else 5 // val rows = if (slots.size % columns == 0) slots.size / columns else 5
val columns = record.verticalCount // val columns = record.verticalCount
val rows = record.horizontalRows // val rows = record.horizontalRows
val rows = record.verticalCount
val columns = record.horizontalRows
log("updateUI: slots=${slots.size}, rows=$rows, columns=$columns") log("updateUI: slots=${slots.size}, rows=$rows, columns=$columns")
list.clear() list.clear()
@@ -328,7 +330,7 @@ class HomeV3Activity : BaseActivity() {
private fun saveGoodsTask() { private fun saveGoodsTask() {
saveTaskJob = saveTaskJob =
taskExecutor.startIntervalTaskWithInitialDelay(10 * 1000L, 2 * 60 * 1000L) { taskExecutor.startIntervalTaskWithInitialDelay(10 * 1000L, 1 * 60 * 1000L) {
syncShelfGoodsToServer() syncShelfGoodsToServer()
} }
} }
@@ -39,6 +39,7 @@ class InitActivity : BaseActivity() {
App.deviceId = AppUtil.getUDID(this) App.deviceId = AppUtil.getUDID(this)
// TODO: 测试设备号 // TODO: 测试设备号
// App.deviceId = "d369f9b0-1c5b-3066-ba72-988e1449cecc" // App.deviceId = "d369f9b0-1c5b-3066-ba72-988e1449cecc"
// App.deviceId = "25b777a9-6298-30d3-a5f8-3b3eef2a50f7"
// App.deviceId = "505ce1b1-facc-3eb2-855a-3dadda5ba358" // App.deviceId = "505ce1b1-facc-3eb2-855a-3dadda5ba358"
Log.d(TAG, "onCreate: deviceId = ${App.deviceId}") Log.d(TAG, "onCreate: deviceId = ${App.deviceId}")
SpTool.put(SpTool.DEVICE_ID, App.deviceId) SpTool.put(SpTool.DEVICE_ID, App.deviceId)
@@ -48,7 +49,7 @@ class InitActivity : BaseActivity() {
// } else { // } else {
// GlobalData.appBaseUrl = GlobalData.PROD_BASE_URL // GlobalData.appBaseUrl = GlobalData.PROD_BASE_URL
// } // }
GlobalData.appBaseUrl = GlobalData.LOCAL_BASE_URL GlobalData.appBaseUrl = GlobalData.TEST_BASE_URL
App.canteenId = "0" App.canteenId = "0"
binding.ivQrCode.invisible() binding.ivQrCode.invisible()
@@ -14,6 +14,8 @@ import com.scwang.smart.refresh.layout.constant.RefreshState
import com.shuwei.intelligent.shelves.R import com.shuwei.intelligent.shelves.R
import com.shuwei.intelligent.shelves.base.BaseActivity import com.shuwei.intelligent.shelves.base.BaseActivity
import com.shuwei.intelligent.shelves.databinding.ActivityShelfV3Binding import com.shuwei.intelligent.shelves.databinding.ActivityShelfV3Binding
import com.shuwei.intelligent.shelves.dialog.ChipSelectDialog
import com.shuwei.intelligent.shelves.dialog.CommonDialog
import com.shuwei.intelligent.shelves.model.SendWeightEvent import com.shuwei.intelligent.shelves.model.SendWeightEvent
import com.shuwei.intelligent.shelves.net.Loading import com.shuwei.intelligent.shelves.net.Loading
import com.shuwei.intelligent.shelves.serial.ScaleManager import com.shuwei.intelligent.shelves.serial.ScaleManager
@@ -25,9 +27,11 @@ import com.shuwei.intelligent.shelves.utils.ext.gone
import com.shuwei.intelligent.shelves.utils.ext.toast import com.shuwei.intelligent.shelves.utils.ext.toast
import com.shuwei.intelligent.shelves.utils.ext.visible import com.shuwei.intelligent.shelves.utils.ext.visible
import com.sw.scalefusion.shelf.adapter.PendingInboundAdapter import com.sw.scalefusion.shelf.adapter.PendingInboundAdapter
import com.sw.scalefusion.shelf.model.FoodItem
import com.sw.scalefusion.shelf.model.PendingInboundItem import com.sw.scalefusion.shelf.model.PendingInboundItem
import com.sw.scalefusion.shelf.model.PendingInboundRequest import com.sw.scalefusion.shelf.model.PendingInboundRequest
import com.sw.scalefusion.shelf.model.PutSlotRequest import com.sw.scalefusion.shelf.model.PutSlotRequest
import com.sw.scalefusion.shelf.model.SearchFoodRequest
import com.sw.scalefusion.shelf.model.SlotDetailRequest import com.sw.scalefusion.shelf.model.SlotDetailRequest
import com.sw.scalefusion.shelf.model.SlotModel import com.sw.scalefusion.shelf.model.SlotModel
import com.sw.scalefusion.shelf.net.NetViewModelV3 import com.sw.scalefusion.shelf.net.NetViewModelV3
@@ -59,18 +63,43 @@ class ShelfV3Activity : BaseActivity() {
private val viewModel: NetViewModelV3 by viewModels() private val viewModel: NetViewModelV3 by viewModels()
private val optionList: MutableList<PendingInboundItem> = mutableListOf() private val optionList: MutableList<FoodItem> = mutableListOf()
private val optionAdapter by lazy { private val optionAdapter by lazy {
PendingInboundAdapter(optionList).apply { PendingInboundAdapter(optionList).apply {
setOnDebouncedItemClick { _, _, position -> setOnDebouncedItemClick { _, _, position ->
optionList.forEachIndexed { index, option -> option.isSelected = index == position } val vegTypeList = getItem(position)?.vegTypeList ?: emptyList()
notifyDataSetChanged() if (vegTypeList.isEmpty()) {
binding.tvFoodName.text = optionList[position].materName selectCategory(position)
KeyboardUtil.hideKeyboard(this@ShelfV3Activity.window.decorView) return@setOnDebouncedItemClick
}
val categoryList = vegTypeList.map { it.vegTypeName }
if (categoryList.isEmpty()) {
CommonDialog(this@ShelfV3Activity).apply {
dialogTitle = "净菜选择"
dialogContent = "暂无净菜类别,请联系管理员添加,或稍后重试"
show()
}
return@setOnDebouncedItemClick
}
showChipSelectDialog(categoryList) { index ->
getItem(position)?.typeSelectedIndex = index
selectCategory(position)
}
} }
} }
} }
private fun selectCategory(position: Int) {
optionList.forEachIndexed { index, option -> option.isSelected = index == position }
optionAdapter.notifyDataSetChanged()
binding.tvFoodName.text = optionList[position].materName
val index = optionList[position].typeSelectedIndex
val typeList = optionList[position].vegTypeList ?: emptyList()
val selectType = typeList.getOrNull(index)?.vegTypeName ?: ""
binding.tvFoodType.text = selectType
KeyboardUtil.hideKeyboard(this@ShelfV3Activity.window.decorView)
}
private var cabinetType: Int = 0 private var cabinetType: Int = 0
private var canteenId: Long = 0 private var canteenId: Long = 0
private var cabinetId: String = "" private var cabinetId: String = ""
@@ -113,6 +142,7 @@ class ShelfV3Activity : BaseActivity() {
/** 从 slotDetail 响应更新 UI */ /** 从 slotDetail 响应更新 UI */
private fun updateUI(model: SlotModel) { private fun updateUI(model: SlotModel) {
binding.tvFoodName.text = if (model.materName.isNullOrBlank()) "-" else model.materName binding.tvFoodName.text = if (model.materName.isNullOrBlank()) "-" else model.materName
binding.tvFoodType.text = ""
val weightG = model.weight ?: 0.0 val weightG = model.weight ?: 0.0
realWeight = (weightG * 1000.0).toInt() realWeight = (weightG * 1000.0).toInt()
binding.tvFoodWeight.text = if (weightG >= 1.0) "%.3f千克".format(weightG) binding.tvFoodWeight.text = if (weightG >= 1.0) "%.3f千克".format(weightG)
@@ -155,7 +185,7 @@ class ShelfV3Activity : BaseActivity() {
binding.btnClearEmpty.setOnClickListener { v -> binding.btnClearEmpty.setOnClickListener { v ->
clearZero() clearZero()
binding.tvFoodName.text = "-" binding.tvFoodName.text = "-"
binding.tvFoodType.text = ""
Loading.show(this@ShelfV3Activity) Loading.show(this@ShelfV3Activity)
v.postDelayed({ v.postDelayed({
Loading.dismiss() Loading.dismiss()
@@ -186,11 +216,12 @@ class ShelfV3Activity : BaseActivity() {
cabinetType = cabinetType, cabinetType = cabinetType,
cabinetId = cabinetId, cabinetId = cabinetId,
slotNo = slotNo, slotNo = slotNo,
materId = item.materId , materId = item.materId,
materName = item.materName, materName = item.materName,
traceCode = item.traceCode,
weight = shelfModel?.weight ?: 0.0 weight = shelfModel?.weight ?: 0.0
), ).also {
it.vegTypeId = item.vegTypeList?.getOrNull(item.typeSelectedIndex)?.vegTypeId
},
onLoading = { showProgress() }, onLoading = { showProgress() },
onSuccess = onSuccess@{ inboundNo -> onSuccess = onSuccess@{ inboundNo ->
Loading.dismiss() Loading.dismiss()
@@ -213,11 +244,10 @@ class ShelfV3Activity : BaseActivity() {
} }
private fun loadList() { private fun loadList() {
viewModel.pendingInbound( viewModel.searchFood(
request = PendingInboundRequest( request = SearchFoodRequest(
cabinetType = shelfModel?.cabinetType ?: 0, cabinetType = shelfModel?.cabinetType ?: 0,
cabinetId = shelfModel?.cabinetId ?: "", keyword = binding.etInputFood.text.toString().trim()
canteenId = canteenId
), ),
onLoading = { showProgress() }, onLoading = { showProgress() },
onSuccess = { items -> updateOptionList(items) }, onSuccess = { items -> updateOptionList(items) },
@@ -230,9 +260,9 @@ class ShelfV3Activity : BaseActivity() {
} }
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
private fun updateOptionList(items: List<PendingInboundItem>?) { private fun updateOptionList(items: List<FoodItem>?) {
finishRefresh() finishRefresh()
binding.include?.root?.gone() binding.include.root.gone()
binding.root.postDelayed({ Loading.dismiss() }, 200) binding.root.postDelayed({ Loading.dismiss() }, 200)
if (items.isNullOrEmpty()) { if (items.isNullOrEmpty()) {
loadEmptyView(); return loadEmptyView(); return
@@ -317,4 +347,14 @@ class ShelfV3Activity : BaseActivity() {
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
window.decorView.postDelayed({ Loading.dismiss() }, 1000) window.decorView.postDelayed({ Loading.dismiss() }, 1000)
} }
private fun showChipSelectDialog(categoryList: List<String?>, callback: (Int) -> Unit) {
ChipSelectDialog(this).apply {
dialogTitle = "请选择净菜分类"
items = categoryList
onItemSelected = callback
show()
}
}
} }
@@ -11,10 +11,10 @@ import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.shuwei.intelligent.shelves.R import com.shuwei.intelligent.shelves.R
import com.shuwei.intelligent.shelves.databinding.ListItemSearchBinding import com.shuwei.intelligent.shelves.databinding.ListItemSearchBinding
import com.sw.scalefusion.shelf.model.PendingInboundItem import com.sw.scalefusion.shelf.model.FoodItem
class PendingInboundAdapter(list: MutableList<PendingInboundItem>) : class PendingInboundAdapter(list: MutableList<FoodItem>) :
BaseQuickAdapter<PendingInboundItem, PendingInboundAdapter.VH>(list) { BaseQuickAdapter<FoodItem, PendingInboundAdapter.VH>(list) {
inner class VH(val binding: ListItemSearchBinding) : QuickViewHolder(binding.root) inner class VH(val binding: ListItemSearchBinding) : QuickViewHolder(binding.root)
@@ -23,7 +23,7 @@ class PendingInboundAdapter(list: MutableList<PendingInboundItem>) :
return VH(binding) return VH(binding)
} }
override fun onBindViewHolder(holder: VH, position: Int, item: PendingInboundItem?) { override fun onBindViewHolder(holder: VH, position: Int, item: FoodItem?) {
item ?: return item ?: return
val isSelected = item.isSelected val isSelected = item.isSelected
holder.binding.btnFoodName.run { holder.binding.btnFoodName.run {
@@ -6,14 +6,20 @@ data class PendingInboundRequest(
var cabinetId: String var cabinetId: String
) )
data class SearchFoodRequest(
var cabinetType: Int,
var keyword: String? = null
)
data class PutSlotRequest( data class PutSlotRequest(
val cabinetType: Int, val cabinetType: Int? = null,
val cabinetId: String, val cabinetId: String? = null,
val slotNo: String, val slotNo: String? = null,
val materId: Long, val materId: Long? = null,
val materName: String, var vegTypeId: Long? = null,
val materName: String? = null,
val traceCode: String? = null, val traceCode: String? = null,
val weight: Double val weight: Double? = null,
) )
data class SlotDetailRequest( data class SlotDetailRequest(
@@ -0,0 +1,25 @@
package com.sw.scalefusion.shelf.model
import com.shuwei.intelligent.shelves.utils.DateTimeUtil
import java.util.Date
data class FoodItem(
var materId:Long? = null,
var materName:String? = null,
var materUrl:String? = null,
var vegTypeList:List<FoodType>? = null,
var isSelected:Boolean = false,
var typeSelectedIndex:Int = -1
) {
/** 转换为 SlotModel,保留原格口的 slotNo/cabinetId 等 */
fun toSlotModel(model: SlotModel) = model.copy(
materId = materId ,
materName = materName,
storeTime = DateTimeUtil.formatDateTime(dateTime = Date()),
)
}
data class FoodType(
var vegTypeId:Long? = null,
var vegTypeName:String? = null
)
@@ -1,9 +1,11 @@
package com.sw.scalefusion.shelf.net package com.sw.scalefusion.shelf.net
import com.shuwei.intelligent.shelves.App import com.shuwei.intelligent.shelves.App
import com.sw.scalefusion.shelf.model.FoodItem
import com.sw.scalefusion.shelf.model.PendingInboundItem import com.sw.scalefusion.shelf.model.PendingInboundItem
import com.sw.scalefusion.shelf.model.PendingInboundRequest import com.sw.scalefusion.shelf.model.PendingInboundRequest
import com.sw.scalefusion.shelf.model.PutSlotRequest import com.sw.scalefusion.shelf.model.PutSlotRequest
import com.sw.scalefusion.shelf.model.SearchFoodRequest
import com.sw.scalefusion.shelf.model.SlotDetailRequest import com.sw.scalefusion.shelf.model.SlotDetailRequest
import com.sw.scalefusion.shelf.model.SlotModel import com.sw.scalefusion.shelf.model.SlotModel
import com.sw.scalefusion.shelf.model.SlotRecord import com.sw.scalefusion.shelf.model.SlotRecord
@@ -23,6 +25,10 @@ interface ApiServiceV3 {
@POST("/nutrition/neglect/mater-cabinet/pending-inbound") @POST("/nutrition/neglect/mater-cabinet/pending-inbound")
suspend fun pendingInbound(@Body request: PendingInboundRequest): ApiResponse<List<PendingInboundItem>?> suspend fun pendingInbound(@Body request: PendingInboundRequest): ApiResponse<List<PendingInboundItem>?>
/** 搜索净菜、毛菜 */
@POST("/nutrition/neglect/mater-cabinet/ingredients")
suspend fun searchFood(@Body request: SearchFoodRequest): ApiResponse<List<FoodItem>?>
/** 全量同步重量 */ /** 全量同步重量 */
@POST("/nutrition/neglect/mater-cabinet/sync-weight") @POST("/nutrition/neglect/mater-cabinet/sync-weight")
suspend fun syncWeight(@Body request: SyncWeightRequest): ApiResponse<Any?> suspend fun syncWeight(@Body request: SyncWeightRequest): ApiResponse<Any?>
@@ -2,9 +2,11 @@ package com.sw.scalefusion.shelf.net
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.sw.scalefusion.shelf.model.FoodItem
import com.sw.scalefusion.shelf.model.PendingInboundItem import com.sw.scalefusion.shelf.model.PendingInboundItem
import com.sw.scalefusion.shelf.model.PendingInboundRequest import com.sw.scalefusion.shelf.model.PendingInboundRequest
import com.sw.scalefusion.shelf.model.PutSlotRequest import com.sw.scalefusion.shelf.model.PutSlotRequest
import com.sw.scalefusion.shelf.model.SearchFoodRequest
import com.sw.scalefusion.shelf.model.SlotDetailRequest import com.sw.scalefusion.shelf.model.SlotDetailRequest
import com.sw.scalefusion.shelf.model.SlotModel import com.sw.scalefusion.shelf.model.SlotModel
import com.sw.scalefusion.shelf.model.SlotRecord import com.sw.scalefusion.shelf.model.SlotRecord
@@ -44,6 +46,16 @@ class NetViewModelV3 : ViewModel() {
} }
} }
/** 搜索净菜、毛菜 */
fun searchFood(request: SearchFoodRequest, onLoading: () -> Unit = {}, onSuccess: (List<FoodItem>?) -> Unit, onError: (String) -> Unit = {}) {
viewModelScope.launch {
onLoading()
val response = repository.searchFood(request)
if (response.isSuccess()) onSuccess(response.data)
else onError(response.msg ?: "请求失败")
}
}
/** 格口详情 */ /** 格口详情 */
fun slotDetail( fun slotDetail(
request: SlotDetailRequest, request: SlotDetailRequest,
@@ -2,9 +2,11 @@ package com.sw.scalefusion.shelf.net
import com.shuwei.intelligent.shelves.App import com.shuwei.intelligent.shelves.App
import com.shuwei.intelligent.shelves.net.apiServiceV3 import com.shuwei.intelligent.shelves.net.apiServiceV3
import com.sw.scalefusion.shelf.model.FoodItem
import com.sw.scalefusion.shelf.model.PendingInboundItem import com.sw.scalefusion.shelf.model.PendingInboundItem
import com.sw.scalefusion.shelf.model.PendingInboundRequest import com.sw.scalefusion.shelf.model.PendingInboundRequest
import com.sw.scalefusion.shelf.model.PutSlotRequest import com.sw.scalefusion.shelf.model.PutSlotRequest
import com.sw.scalefusion.shelf.model.SearchFoodRequest
import com.sw.scalefusion.shelf.model.SlotDetailRequest import com.sw.scalefusion.shelf.model.SlotDetailRequest
import com.sw.scalefusion.shelf.model.SlotModel import com.sw.scalefusion.shelf.model.SlotModel
import com.sw.scalefusion.shelf.model.SlotRecord import com.sw.scalefusion.shelf.model.SlotRecord
@@ -20,6 +22,9 @@ class ShelfRepository : BaseRepository() {
suspend fun pendingInbound(request: PendingInboundRequest): ApiResponse<List<PendingInboundItem>?> = suspend fun pendingInbound(request: PendingInboundRequest): ApiResponse<List<PendingInboundItem>?> =
safeApiCall { apiServiceV3.pendingInbound(request) } safeApiCall { apiServiceV3.pendingInbound(request) }
/** 搜索净菜、毛菜 */
suspend fun searchFood(request: SearchFoodRequest): ApiResponse<List<FoodItem>?> =
safeApiCall { apiServiceV3.searchFood(request) }
/** 全量同步重量 */ /** 全量同步重量 */
suspend fun syncWeight(request: SyncWeightRequest): ApiResponse<Any?> = suspend fun syncWeight(request: SyncWeightRequest): ApiResponse<Any?> =
safeApiCall { apiServiceV3.syncWeight(request) } safeApiCall { apiServiceV3.syncWeight(request) }
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/bg_card_blue" android:state_checked="true" />
<item android:color="@color/white" android:state_checked="false" />
</selector>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/bg_card_blue" android:state_checked="false" />
<item android:color="@android:color/transparent" android:state_checked="true" />
</selector>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/white" android:state_checked="true" />
<item android:color="@color/bg_card_blue" android:state_checked="false" />
</selector>
+11 -1
View File
@@ -74,6 +74,16 @@
android:textStyle="bold" android:textStyle="bold"
tools:text="金针菇" /> tools:text="金针菇" />
<TextView
android:id="@+id/tvFoodType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/food_name_black"
android:textSize="22sp"
tools:text="金针菇" />
<Space <Space
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_height="0dp"
@@ -139,7 +149,7 @@
android:background="@drawable/shape_search" android:background="@drawable/shape_search"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal"
android:visibility="gone"> android:visibility="visible">
<ImageView <ImageView
android:layout_width="32dp" android:layout_width="32dp"
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="12dp"
app:cardElevation="0dp">
<LinearLayout
android:layout_width="600dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- 标题 -->
<TextView
android:id="@+id/tvDialogTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dp"
android:gravity="center"
android:textColor="#ff141428"
android:textSize="32sp"
android:textStyle="bold" />
<!-- ChipGroup 选择区域 -->
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp"
android:layout_marginVertical="40dp"
app:selectionRequired="false"
app:singleSelection="true" />
<!-- 分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#FFDCDCF0" />
<!-- 底部按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="72dp"
android:gravity="center"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnCancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/white"
android:text="取消"
android:textColor="@android:color/darker_gray"
android:textSize="24sp" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#FFDCDCF0" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnConfirm"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/white"
android:text="确定"
android:textColor="@color/bg_card_blue"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>