feat(setting): 添加调料配置功能并优化界面布局

- 在设置页面添加调料配置按钮和设备切换功能
- 将设备配置页面标题从"设备配置"改为"设备切换"
- 新增SeasoningConfigFragment调料配置片段
- 将秤数据监控按钮可见性从gone改为visible
- 优化collectFragment布局加载方式
- 在DeviceConfigActivity中添加调试日志输出
- 重构SettingActivity中的按钮样式管理逻辑
- 调整fragment列表顺序和点击事件处理
- 修改列表项高度以改善界面显示效果
- 注释掉DeviceConfigFragment中未使用的viewModel相关代码
This commit is contained in:
2026-04-17 11:45:08 +08:00
parent 1ca25e6a1d
commit c35572dc41
9 changed files with 236 additions and 192 deletions
@@ -37,6 +37,7 @@ import com.shuwei.dish.match.dialog.SeasoningSearchDialog
import com.shuwei.dish.match.utils.SpTool import com.shuwei.dish.match.utils.SpTool
import com.shuwei.dish.match.utils.ext.clickWithDebounce import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.gone import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.toJsonString
class DeviceConfigActivity : BaseActivity() { class DeviceConfigActivity : BaseActivity() {
@@ -223,6 +224,7 @@ class DeviceConfigActivity : BaseActivity() {
} }
private fun setGridData(list: MutableList<SeasoningEntity>) { private fun setGridData(list: MutableList<SeasoningEntity>) {
Log.d(TAG, "setGridData: ${list.toJsonString()}")
val gridLayout = binding.include.root val gridLayout = binding.include.root
list.forEach { entity -> list.forEach { entity ->
val tag = entity.sort.toString() val tag = entity.sort.toString()
@@ -3,10 +3,12 @@ package com.shuwei.dish.match.ui
import android.Manifest import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Color
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatButton
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.toColorInt import androidx.core.graphics.toColorInt
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@@ -20,6 +22,7 @@ import com.shuwei.dish.match.databinding.ActivitySettingBinding
import com.shuwei.dish.match.databinding.LayoutCameraPreviewBinding import com.shuwei.dish.match.databinding.LayoutCameraPreviewBinding
import com.shuwei.dish.match.ui.fragment.CollectFragment import com.shuwei.dish.match.ui.fragment.CollectFragment
import com.shuwei.dish.match.ui.fragment.DeviceConfigFragment import com.shuwei.dish.match.ui.fragment.DeviceConfigFragment
import com.shuwei.dish.match.ui.fragment.SeasoningConfigFragment
import com.shuwei.dish.match.utils.CameraUtils import com.shuwei.dish.match.utils.CameraUtils
import com.shuwei.dish.match.utils.SpTool import com.shuwei.dish.match.utils.SpTool
import com.shuwei.dish.match.utils.ext.dp import com.shuwei.dish.match.utils.ext.dp
@@ -72,18 +75,29 @@ class SettingActivity : BaseActivity() {
// 设备配置按钮点击事件 // 设备配置按钮点击事件
binding.btnDeviceConfig.setOnClickListener { binding.btnDeviceConfig.setOnClickListener {
showDeviceConfigFragment() showDeviceConfigFragment()
updateButtonColors(isDeviceConfigSelected = true)
loadTabStyle(button = binding.btnDeviceConfig, isSelected = true)
loadTabStyle(button = binding.btnSeasoningConfig, isSelected = false)
loadTabStyle(button = binding.btnFoodCollect, isSelected = false)
}
// 调料配置按钮点击事件
binding.btnSeasoningConfig.setOnClickListener {
showSeasoningConfigFragment()
loadTabStyle(button = binding.btnDeviceConfig, isSelected = false)
loadTabStyle(button = binding.btnSeasoningConfig, isSelected = true)
loadTabStyle(button = binding.btnFoodCollect, isSelected = false)
} }
// 菜品采集按钮点击事件 // 菜品采集按钮点击事件
binding.btnFoodCollect.setOnClickListener { binding.btnFoodCollect.setOnClickListener {
checkCameraPermissionAndShowFragment() checkCameraPermissionAndShowFragment()
updateButtonColors(isDeviceConfigSelected = false)
}
// // 设备角色只读展示,角色由设备 ID 决定,不可手动切换 loadTabStyle(button = binding.btnDeviceConfig, isSelected = false)
// updateRoleButtonText() loadTabStyle(button = binding.btnSeasoningConfig, isSelected = false)
// binding.btnDeviceRole.isEnabled = false loadTabStyle(button = binding.btnFoodCollect, isSelected = true)
}
// 主设备显示「秤数据监控」入口 // 主设备显示「秤数据监控」入口
if (GlobalData.deviceRole == DeviceRole.MASTER) { if (GlobalData.deviceRole == DeviceRole.MASTER) {
@@ -94,7 +108,10 @@ class SettingActivity : BaseActivity() {
} }
// 初始化按钮颜色(默认设备配置为选中状态) // 初始化按钮颜色(默认设备配置为选中状态)
updateButtonColors(isDeviceConfigSelected = true)
loadTabStyle(button = binding.btnDeviceConfig, isSelected = true)
loadTabStyle(button = binding.btnSeasoningConfig, isSelected = false)
loadTabStyle(button = binding.btnFoodCollect, isSelected = false)
} }
// /** 刷新角色按钮文字 */ // /** 刷新角色按钮文字 */
@@ -104,43 +121,26 @@ class SettingActivity : BaseActivity() {
// } // }
/** /**
* 更新底部菜单按钮的颜色状态 * 加载顶部Tab按钮样式
* @param isDeviceConfigSelected 设备配置按钮是否被选中 *
* @param button 按钮
* @param isSelected 是否选中
*/ */
private fun updateButtonColors(isDeviceConfigSelected: Boolean) { private fun loadTabStyle(button: AppCompatButton, isSelected: Boolean) {
val selectedColor = "#FFFFFF".toColorInt() // 选中颜色(白色) button.apply {
val unselectedColor = "#5E7585".toColorInt() // 未选中颜色(灰色) if (isSelected){
// 选中
if (isDeviceConfigSelected) { setTextColor(Color.WHITE)
// 设备配置按钮:选中状态
binding.btnDeviceConfig.apply {
setTextColor(selectedColor)
textSize = 28f textSize = 28f
setTypeface(null, android.graphics.Typeface.BOLD) setTypeface(null, android.graphics.Typeface.BOLD)
background = ContextCompat.getDrawable(this@SettingActivity, R.drawable.bg_btn_underline) background = ContextCompat.getDrawable(this@SettingActivity, R.drawable.bg_btn_underline)
}
// 采集食材按钮:未选中状态
binding.btnFoodCollect.apply {
setTextColor(unselectedColor)
textSize = 26f
setTypeface(null, android.graphics.Typeface.NORMAL)
background = null
}
} else { } else {
// 设备配置按钮:未选中状态 // 未选中
binding.btnDeviceConfig.apply { setTextColor("#5E7585".toColorInt())
setTextColor(unselectedColor)
textSize = 26f textSize = 26f
setTypeface(null, android.graphics.Typeface.NORMAL) setTypeface(null, android.graphics.Typeface.NORMAL)
background = null background = null
} }
// 采集食材按钮:选中状态
binding.btnFoodCollect.apply {
setTextColor(selectedColor)
textSize = 28f
setTypeface(null, android.graphics.Typeface.BOLD)
background = ContextCompat.getDrawable(this@SettingActivity, R.drawable.bg_btn_underline)
}
} }
} }
@@ -149,9 +149,10 @@ class SettingActivity : BaseActivity() {
*/ */
@SuppressLint("ObsoleteSdkInt") @SuppressLint("ObsoleteSdkInt")
private fun checkCameraPermissionAndShowFragment() { private fun checkCameraPermissionAndShowFragment() {
val collectFragment = fragmentList[2]
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Android 6.0 以下,直接显示 Fragment // Android 6.0 以下,直接显示 Fragment
showFragment(fragmentList[1]) showFragment(collectFragment)
return return
} }
if (ContextCompat.checkSelfPermission( if (ContextCompat.checkSelfPermission(
@@ -160,13 +161,13 @@ class SettingActivity : BaseActivity() {
) == PackageManager.PERMISSION_GRANTED ) == PackageManager.PERMISSION_GRANTED
) { ) {
// 权限已授予,直接显示 Fragment // 权限已授予,直接显示 Fragment
showFragment(fragmentList[1]) showFragment(collectFragment)
} else { } else {
// 权限未授予,申请权限 // 权限未授予,申请权限
requestPermission(Manifest.permission.CAMERA) { isGranted -> requestPermission(Manifest.permission.CAMERA) { isGranted ->
if (isGranted) { if (isGranted) {
// 权限已授予,显示 CollectFragment // 权限已授予,显示 CollectFragment
showFragment(fragmentList[1]) showFragment(collectFragment)
} else { } else {
// 权限被拒绝 // 权限被拒绝
toast("暂无相机权限,无法使用菜品采集功能") toast("暂无相机权限,无法使用菜品采集功能")
@@ -216,19 +217,22 @@ class SettingActivity : BaseActivity() {
} }
/** /**
* 显示设备配置Fragment * 显示设备切换Fragment
*/ */
private fun showDeviceConfigFragment() { private fun showDeviceConfigFragment() {
// val fragment = DeviceConfigFragment.newInstance()
// supportFragmentManager.beginTransaction()
// .replace(binding.fragmentContainer.id, fragment)
// .addToBackStack(null)
// .commit()
showFragment(fragmentList[0]) showFragment(fragmentList[0])
} }
/**
* 显示设调料配置Fragment
*/
private fun showSeasoningConfigFragment() {
showFragment(fragmentList[1])
}
private val fragmentList = mutableListOf<Fragment>().apply { private val fragmentList = mutableListOf<Fragment>().apply {
add(DeviceConfigFragment.newInstance()) add(DeviceConfigFragment.newInstance())
add(SeasoningConfigFragment())
add(CollectFragment()) add(CollectFragment())
} }
@@ -82,7 +82,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup? container: ViewGroup?
): FragmentCollectBinding { ): FragmentCollectBinding {
return FragmentCollectBinding.inflate(LayoutInflater.from(context)) return FragmentCollectBinding.inflate(inflater, container, false)
} }
//typealias CameraCallback = (Uri) -> Unit //typealias CameraCallback = (Uri) -> Unit
@@ -73,7 +73,7 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
var modeDesc: String var modeDesc: String
) )
private lateinit var appViewModel: AppViewModel // private lateinit var appViewModel: AppViewModel
private var cookMode: Int = 0 private var cookMode: Int = 0
private val weightArray = SparseArray<Double>() private val weightArray = SparseArray<Double>()
@@ -92,18 +92,18 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
cookMode = arguments?.getInt(COOK_MODE, 0) ?: 0 cookMode = arguments?.getInt(COOK_MODE, 0) ?: 0
initViewModel() initViewModel()
initUI() initUI()
addWeighListener() // addWeighListener()
addGridItemListener() // addGridItemListener()
loadSeasoning() // loadSeasoning()
} }
/** /**
* 初始化ViewModel * 初始化ViewModel
*/ */
private fun initViewModel() { private fun initViewModel() {
val db = BaseApp.instance!!.database // val db = BaseApp.instance!!.database
val factory = AppFactory(AppRepository(db.appDao())) // val factory = AppFactory(AppRepository(db.appDao()))
appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java] // appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
} }
/** /**
@@ -156,138 +156,138 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
activity?.finish() activity?.finish()
} }
} }
//
/** // /**
* 添加称重监听 // * 添加称重监听
*/ // */
private fun addWeighListener() { // private fun addWeighListener() {
WeightUtil.addWeightListener( // WeightUtil.addWeightListener(
weightKey = TAG, // weightKey = TAG,
getWeight = { address, state, weight -> // getWeight = { address, state, weight ->
Log.d(TAG, "addWeighListener: address=$address,stat=$state,weight=$weight") // Log.d(TAG, "addWeighListener: address=$address,stat=$state,weight=$weight")
weightArray.put(address, weight) // weightArray.put(address, weight)
val item = seasoningItems.firstOrNull { address == addressArray[it.sort] } // val item = seasoningItems.firstOrNull { address == addressArray[it.sort] }
item?.let { // item?.let {
it.useWeight = weight.toDouble() // it.useWeight = weight.toDouble()
updateGridData(it) // updateGridData(it)
} // }
Log.d(TAG, "addWeighListener: update-----------------------") // Log.d(TAG, "addWeighListener: update-----------------------")
}) // })
} // }
//
/** // /**
* 添加网格项点击监听 // * 添加网格项点击监听
*/ // */
private fun addGridItemListener() { // private fun addGridItemListener() {
binding.include.root.forEach { child -> // binding.include.root.forEach { child ->
child.clickWithDebounce { // child.clickWithDebounce {
val sort = child.tag.toString().toInt() // val sort = child.tag.toString().toInt()
val entity = seasoningItems.firstOrNull { it.sort == sort } ?: SeasoningEntity() // val entity = seasoningItems.firstOrNull { it.sort == sort } ?: SeasoningEntity()
clickGridItem(sort, entity) // clickGridItem(sort, entity)
} // }
} // }
} // }
//
/** // /**
* 加载调料数据 // * 加载调料数据
*/ // */
private fun loadSeasoning() { // private fun loadSeasoning() {
appViewModel.loadSeasoning { //// appViewModel.loadSeasoning {
seasoningItems.clear() //// seasoningItems.clear()
seasoningItems.addAll(it) //// seasoningItems.addAll(it)
initConfigData() //// initConfigData()
setGridData(seasoningItems) //// setGridData(seasoningItems)
} //// }
} // }
//
/** // /**
* 初始化配置数据,确保有12个调料位置 // * 初始化配置数据,确保有12个调料位置
*/ // */
private fun initConfigData() { // private fun initConfigData() {
repeat(12) { num -> // repeat(12) { num ->
val firstOne = seasoningItems.firstOrNull { it.sort == num } // val firstOne = seasoningItems.firstOrNull { it.sort == num }
if (firstOne == null) { // if (firstOne == null) {
seasoningItems.add(SeasoningEntity().also { it.sort = num }) // seasoningItems.add(SeasoningEntity().also { it.sort = num })
} // }
} // }
} // }
//
/** // /**
* 设置网格数据 // * 设置网格数据
*/ // */
private fun setGridData(list: MutableList<SeasoningEntity>) { // private fun setGridData(list: MutableList<SeasoningEntity>) {
val gridLayout = binding.include.root // val gridLayout = binding.include.root
list.forEach { entity -> // list.forEach { entity ->
val tag = entity.sort.toString() // val tag = entity.sort.toString()
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag) // val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
TextCellAdapter.loadLayout(frameLayout, entity) // TextCellAdapter.loadLayout(frameLayout, entity)
} // }
} // }
//
/** // /**
* 更新网格数据 // * 更新网格数据
*/ // */
private fun updateGridData(entity: SeasoningEntity) { // private fun updateGridData(entity: SeasoningEntity) {
val gridLayout = binding.include.root // val gridLayout = binding.include.root
val tag = entity.sort.toString() // val tag = entity.sort.toString()
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag) // val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
TextCellAdapter.loadLayout(frameLayout, entity) // TextCellAdapter.loadLayout(frameLayout, entity)
} // }
//
/** // /**
* 点击网格项,打开调料搜索对话框 // * 点击网格项,打开调料搜索对话框
*/ // */
private fun clickGridItem(sort: Int, entity: SeasoningEntity) { // private fun clickGridItem(sort: Int, entity: SeasoningEntity) {
val currentAddress = AddressUtil.getWeighAddressArray().get(sort) // val currentAddress = AddressUtil.getWeighAddressArray().get(sort)
SeasoningSearchDialog( // SeasoningSearchDialog(
activity = requireActivity() as BaseActivity, // activity = requireActivity() as BaseActivity,
weighIndex = sort, // weighIndex = sort,
weighAddress = currentAddress, // weighAddress = currentAddress,
clickName = entity.goodsName // clickName = entity.goodsName
) { item -> // ) { item ->
syncItem(entity, item) // syncItem(entity, item)
// 3-调料 // // 3-调料
entity.materialType = 3 // entity.materialType = 3
entity.sort = sort // entity.sort = sort
saveSeasoning(entity) { // saveSeasoning(entity) {
val tag = sort.toString() // val tag = sort.toString()
val gridLayout = binding.include.root // val gridLayout = binding.include.root
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag) // val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
TextCellAdapter.loadLayout(frameLayout, entity) // TextCellAdapter.loadLayout(frameLayout, entity)
} // }
}.show() // }.show()
} // }
//
/** // /**
* 同步调料项数据 // * 同步调料项数据
*/ // */
private fun syncItem(oldItem: SeasoningEntity, newItem: SeasoningEntity) { // private fun syncItem(oldItem: SeasoningEntity, newItem: SeasoningEntity) {
oldItem.run { // oldItem.run {
goodsId = newItem.goodsId // goodsId = newItem.goodsId
goodsName = newItem.goodsName // goodsName = newItem.goodsName
goodsOrRelationCode = newItem.goodsOrRelationCode // goodsOrRelationCode = newItem.goodsOrRelationCode
relateionType = newItem.relateionType // relateionType = newItem.relateionType
materialType = newItem.materialType // materialType = newItem.materialType
allEdible = newItem.allEdible // allEdible = newItem.allEdible
useWeight = newItem.useWeight // useWeight = newItem.useWeight
popularName = newItem.popularName // popularName = newItem.popularName
canteenId = newItem.canteenId // canteenId = newItem.canteenId
relateionType_dictText = newItem.relateionType_dictText // relateionType_dictText = newItem.relateionType_dictText
//
foodId = newItem.foodId // foodId = newItem.foodId
sort = newItem.sort // sort = newItem.sort
} // }
} // }
//
/** // /**
* 保存调料数据 // * 保存调料数据
*/ // */
fun saveSeasoning(entity: SeasoningEntity, action: () -> Unit = {}) { // fun saveSeasoning(entity: SeasoningEntity, action: () -> Unit = {}) {
appViewModel.saveSeasoning(entity) { // appViewModel.saveSeasoning(entity) {
action() // action()
toast("保存成功") // toast("保存成功")
} // }
} // }
/** /**
* 加载品控模式文本样式 * 加载品控模式文本样式
@@ -359,6 +359,6 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
// 移除称重监听 // 移除称重监听
WeightUtil.removeWeightListener(TAG) // WeightUtil.removeWeightListener(TAG)
} }
} }
@@ -0,0 +1,22 @@
package com.shuwei.dish.match.ui.fragment
import android.view.LayoutInflater
import android.view.ViewGroup
import com.shuwei.dish.match.base.BaseFragment
import com.shuwei.dish.match.databinding.FragmentSeasoningConfigBinding
import com.shuwei.dish.match.ui.SettingActivity
class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
) = FragmentSeasoningConfigBinding.inflate(inflater, container, false)
private lateinit var settingActivity: SettingActivity
override fun initialize() {
settingActivity = activity as SettingActivity
}
}
+11 -2
View File
@@ -23,11 +23,20 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="70dp" android:layout_height="70dp"
android:layout_weight="1" android:layout_weight="1"
android:text="设备配置" android:text="设备切换"
android:textSize="28sp" android:textSize="28sp"
android:textStyle="bold" android:textStyle="bold"
android:background="@android:color/transparent" /> android:background="@android:color/transparent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnSeasoningConfig"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_weight="1"
android:text="调料配置"
android:textSize="26sp"
android:background="@android:color/transparent" />
<androidx.appcompat.widget.AppCompatButton <androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnFoodCollect" android:id="@+id/btnFoodCollect"
android:layout_width="0dp" android:layout_width="0dp"
@@ -53,7 +62,7 @@
android:layout_weight="1" android:layout_weight="1"
android:text="秤数据监控" android:text="秤数据监控"
android:textSize="26sp" android:textSize="26sp"
android:visibility="gone" android:visibility="visible"
android:background="@android:color/transparent" /> android:background="@android:color/transparent" />
</LinearLayout> </LinearLayout>
@@ -10,8 +10,7 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="600dp"
android:layout_weight="1"
android:layout_marginStart="30dp" android:layout_marginStart="30dp"
android:layout_marginEnd="30dp" android:layout_marginEnd="30dp"
android:background="@drawable/shape_white_30_corners" android:background="@drawable/shape_white_30_corners"
@@ -100,7 +99,8 @@
android:orientation="vertical" android:orientation="vertical"
android:gravity="center_vertical" android:gravity="center_vertical"
android:layout_marginStart="30dp" android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"> android:layout_marginEnd="30dp"
android:visibility="gone">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg_color">
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -3,7 +3,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="120dp"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"