refactor(ui): 移除设备配置页面并重构调料配置界面

- 移除 DeviceConfigActivity 页面及相关 AndroidManifest 注册
- 将调料配置从单页网格改为上下两层 RecyclerView 结构
- 上层使用 FlexboxLayoutManager 显示 22 格调料位
- 下层使用 GridLayoutManager 显示 18 格调料位
- 更新存储工具类 SpTool 中烹饪模式的访问方式
- 修改首页和初始化页面中烹饪模式的读取逻辑
- 更新 WebSocket 客户端连接逻辑中的重复连接处理
This commit is contained in:
2026-04-17 14:23:44 +08:00
parent c35572dc41
commit 77df4a4d82
10 changed files with 469 additions and 374 deletions
+2 -2
View File
@@ -93,8 +93,8 @@
android:theme="@style/Theme.DishMatch.NoSplash" android:theme="@style/Theme.DishMatch.NoSplash"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" /> tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity android:name="com.shuwei.dish.match.ui.DeviceConfigActivity" <!-- <activity android:name="com.shuwei.dish.match.ui.DeviceConfigActivity"-->
android:theme="@style/Theme.DishMatch.NoSplash" /> <!-- android:theme="@style/Theme.DishMatch.NoSplash" />-->
<activity android:name="com.shuwei.dish.match.ui.SettingActivity" <activity android:name="com.shuwei.dish.match.ui.SettingActivity"
android:theme="@style/Theme.DishMatch.NoSplash" android:theme="@style/Theme.DishMatch.NoSplash"
android:screenOrientation="portrait" android:screenOrientation="portrait"
@@ -60,6 +60,8 @@ class ScaleWebSocketClient {
*/ */
fun connect(deviceId: String, host: String, port: Int) { fun connect(deviceId: String, host: String, port: Int) {
removedDevices.remove(deviceId) removedDevices.remove(deviceId)
// 取消旧 IP 的重连任务,防止 IP 变化时新旧任务并发竞争
reconnectTasks.remove(deviceId)?.cancel(false)
reconnectDelays[deviceId] = RECONNECT_BASE_MS reconnectDelays[deviceId] = RECONNECT_BASE_MS
doConnect(deviceId, host, port) doConnect(deviceId, host, port)
} }
@@ -1,347 +1,347 @@
package com.shuwei.dish.match.ui //package com.shuwei.dish.match.ui
//
import android.graphics.Typeface //import android.graphics.Typeface
import android.os.Bundle //import android.os.Bundle
import android.text.SpannableStringBuilder //import android.text.SpannableStringBuilder
import android.text.style.AbsoluteSizeSpan //import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan //import android.text.style.ForegroundColorSpan
import android.text.style.LineHeightSpan //import android.text.style.LineHeightSpan
import android.text.style.StyleSpan //import android.text.style.StyleSpan
import android.util.Log //import android.util.Log
import android.util.SparseArray //import android.util.SparseArray
import android.widget.FrameLayout //import android.widget.FrameLayout
import androidx.core.graphics.toColorInt //import androidx.core.graphics.toColorInt
import androidx.core.view.forEach //import androidx.core.view.forEach
import androidx.lifecycle.ViewModelProvider //import androidx.lifecycle.ViewModelProvider
import com.shuwei.dish.match.base.BaseActivity //import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp //import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.db.AppRepository //import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.dialog.CommonDialog //import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.entity.SeasoningEntity //import com.shuwei.dish.match.entity.SeasoningEntity
import com.shuwei.dish.match.entity.ResetReasoningRecord //import com.shuwei.dish.match.entity.ResetReasoningRecord
import com.shuwei.dish.match.utils.AddressUtil //import com.shuwei.dish.match.utils.AddressUtil
import com.shuwei.dish.match.utils.JsonAssetsLoader //import com.shuwei.dish.match.utils.JsonAssetsLoader
import com.shuwei.dish.match.utils.MultiClickDetector //import com.shuwei.dish.match.utils.MultiClickDetector
import com.shuwei.dish.match.utils.WeightUtil //import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.appendText //import com.shuwei.dish.match.utils.ext.appendText
import com.shuwei.dish.match.utils.ext.buildSpannableString //import com.shuwei.dish.match.utils.ext.buildSpannableString
import com.shuwei.dish.match.utils.ext.dp //import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.startActivity //import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toast //import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible //import com.shuwei.dish.match.utils.ext.visible
import com.shuwei.dish.match.viewmodel.AppViewModel //import com.shuwei.dish.match.viewmodel.AppViewModel
import com.shuwei.dish.match.viewmodel.factory.AppFactory //import com.shuwei.dish.match.viewmodel.factory.AppFactory
import com.shuwei.dish.match.adapter.TextCellAdapter //import com.shuwei.dish.match.adapter.TextCellAdapter
import com.shuwei.dish.match.databinding.ActivityDeviceConfigBinding //import com.shuwei.dish.match.databinding.ActivityDeviceConfigBinding
import com.shuwei.dish.match.dialog.SeasoningSearchDialog //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 //import com.shuwei.dish.match.utils.ext.toJsonString
//
class DeviceConfigActivity : BaseActivity() { //class DeviceConfigActivity : BaseActivity() {
//
companion object { // companion object {
//
const val TAG = "DeviceConfigActivity" // const val TAG = "DeviceConfigActivity"
//
const val COOK_MODE = "cookMode" // const val COOK_MODE = "cookMode"
//
val modeList = listOf<ModeBean>( // val modeList = listOf<ModeBean>(
ModeBean("制作模式", "菜品快速制作,记录熟重"), // ModeBean("制作模式", "菜品快速制作,记录熟重"),
ModeBean("采样模式", "菜品快速制作,记录熟重"), // ModeBean("采样模式", "菜品快速制作,记录熟重"),
ModeBean("品控模式", "菜品快速制作,记录熟重") // ModeBean("品控模式", "菜品快速制作,记录熟重")
) // )
} // }
//
data class ModeBean( // data class ModeBean(
var modeName: String, // var modeName: String,
var modeDesc: String // var modeDesc: String
) // )
//
private lateinit var binding: ActivityDeviceConfigBinding // private lateinit var binding: ActivityDeviceConfigBinding
//
private lateinit var appViewModel: AppViewModel // private lateinit var appViewModel: AppViewModel
//
private var cookMode: Int = 0 // private var cookMode: Int = 0
// private val weightArray = SparseIntArray() //// private val weightArray = SparseIntArray()
private val weightArray = SparseArray<Double>() // private val weightArray = SparseArray<Double>()
private val addressArray = AddressUtil.getWeighAddressArray() // private val addressArray = AddressUtil.getWeighAddressArray()
//
override fun onCreate(savedInstanceState: Bundle?) { // override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) // super.onCreate(savedInstanceState)
binding = ActivityDeviceConfigBinding.inflate(layoutInflater) // binding = ActivityDeviceConfigBinding.inflate(layoutInflater)
setContentView(binding.root) // setContentView(binding.root)
cookMode = intent.getIntExtra(COOK_MODE, 0) // cookMode = intent.getIntExtra(COOK_MODE, 0)
initViewModel() // initViewModel()
setHeaderBackground() // setHeaderBackground()
setTitleBar(titleBarAction = { // setTitleBar(titleBarAction = {
it.visible() // it.visible()
}, titleAction = { // }, titleAction = {
it.text = "设备配置" // it.text = "设备配置"
}, rightIconActon = { // }, rightIconActon = {
it.gone() // it.gone()
// it.alpha = 0.0F //// it.alpha = 0.0F
// it.setImageResource(R.drawable.ic_setting) //// it.setImageResource(R.drawable.ic_setting)
// it.setOnClickListener {_-> //// it.setOnClickListener {_->
// detector.setOnDelayedMultiClickListener(it) { //// detector.setOnDelayedMultiClickListener(it) {
// defaultDataSettingDialog() //// defaultDataSettingDialog()
//// }
//// }
// })
//
// loadQualitySpan(isEnable = false)
// when (cookMode) {
// 1 -> {
// binding.rbModeCook.isChecked = true
// binding.rbModeSampling.isChecked = false
// loadCookSpan(isClicked = true)
// loadSamplingSpan()
// }
//
// 2 -> {
// binding.rbModeCook.isChecked = false
// binding.rbModeSampling.isChecked = true
// loadCookSpan()
// loadSamplingSpan(isClicked = true)
// }
//
// else -> {
// binding.rbModeCook.isChecked = true
// binding.rbModeSampling.isChecked = false
// loadCookSpan(isClicked = true)
// loadSamplingSpan()
// } // }
// } // }
}) //
// binding.rbModeCook.setOnClickListener {
loadQualitySpan(isEnable = false) // SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 0)
when (cookMode) { // binding.rbModeCook.isChecked = true
1 -> { // binding.rbModeSampling.isChecked = false
binding.rbModeCook.isChecked = true // loadCookSpan(isClicked = true)
binding.rbModeSampling.isChecked = false // loadSamplingSpan()
loadCookSpan(isClicked = true) // startActivity<SelectDishActivity> {
loadSamplingSpan() // putExtra(SelectDishActivity.IS_CONFIG_PAGE, true)
} // }
// finish()
2 -> { // }
binding.rbModeCook.isChecked = false // binding.rbModeSampling.setOnClickListener {
binding.rbModeSampling.isChecked = true // SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 1)
loadCookSpan() // binding.rbModeCook.isChecked = false
loadSamplingSpan(isClicked = true) // binding.rbModeSampling.isChecked = true
} // loadCookSpan()
// loadSamplingSpan(isClicked = true)
else -> { // startActivity<SamplingListActivity> {
binding.rbModeCook.isChecked = true // putExtra(SamplingListActivity.IS_CONFIG_PAGE, true) }
binding.rbModeSampling.isChecked = false // finish()
loadCookSpan(isClicked = true) // }
loadSamplingSpan() // addWeighListener()
} // addGridItemListener()
}
binding.rbModeCook.setOnClickListener {
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 0)
binding.rbModeCook.isChecked = true
binding.rbModeSampling.isChecked = false
loadCookSpan(isClicked = true)
loadSamplingSpan()
startActivity<SelectDishActivity> {
putExtra(SelectDishActivity.IS_CONFIG_PAGE, true)
}
finish()
}
binding.rbModeSampling.setOnClickListener {
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 1)
binding.rbModeCook.isChecked = false
binding.rbModeSampling.isChecked = true
loadCookSpan()
loadSamplingSpan(isClicked = true)
startActivity<SamplingListActivity> {
putExtra(SamplingListActivity.IS_CONFIG_PAGE, true) }
finish()
}
addWeighListener()
addGridItemListener()
loadSeasoning()
}
private fun addWeighListener() {
WeightUtil.addWeightListener(
weightKey = TAG,
getWeight = { address, state, weight ->
Log.d(TAG, "addWeighListener: address=$address,stat=$state,weight=$weight")
weightArray.put(address, weight)
val item = seasoningItems.firstOrNull { address == addressArray[it.sort] }
item?.let {
it.useWeight = weight.toDouble()
updateGridData(it)
}
Log.d(TAG, "addWeighListener: update-----------------------")
})
}
private var seasoningItems = mutableListOf<SeasoningEntity>()
private fun addGridItemListener() {
binding.include.root.forEach { child ->
child.clickWithDebounce {
val sort = child.tag.toString().toInt()
val entity = seasoningItems.firstOrNull { it.sort == sort } ?: SeasoningEntity()
clickGridItem(sort, entity)
}
}
}
val detector = MultiClickDetector(targetCount = 10, intervalMs = 800)
private fun defaultDataSettingDialog() {
CommonDialog(this)
.setTitle("温馨提示")
.setContent("您好,使用默认配置作为您的调料数据,则已有配置将被清除,确认吗?")
.setNegativeButton("取消")
.setPositiveButton("确认") { resetList() }
.setOnDismissCallback { hideStatusBar() }
.show()
}
private fun resetList() {
runCatching {
val record = JsonAssetsLoader.parseJsonFromAssets<ResetReasoningRecord>(
this,
"default_seasoning_list.json"
)
// val weightArray = WeightUtil.weightArray
appViewModel.clearAllSeasoning {
record?.list?.forEach { entity ->
entity.useWeight = weightArray[addressArray[entity.sort]].toDouble()
appViewModel.saveSeasoning(entity) {
updateGridData(entity)
}
}
// loadSeasoning() // loadSeasoning()
} // }
}.onFailure { it.printStackTrace() } //
} // private fun addWeighListener() {
// WeightUtil.addWeightListener(
private fun initViewModel() { // weightKey = TAG,
val db = BaseApp.instance!!.database // getWeight = { address, state, weight ->
val factory = // Log.d(TAG, "addWeighListener: address=$address,stat=$state,weight=$weight")
AppFactory(AppRepository(db.appDao())) // weightArray.put(address, weight)
appViewModel = // val item = seasoningItems.firstOrNull { address == addressArray[it.sort] }
ViewModelProvider(this, factory)[AppViewModel::class.java] // item?.let {
} // it.useWeight = weight.toDouble()
// updateGridData(it)
private fun loadSeasoning() { // }
appViewModel.loadSeasoning { // Log.d(TAG, "addWeighListener: update-----------------------")
seasoningItems.clear() // })
seasoningItems.addAll(it) // }
initConfigData() //
setGridData(seasoningItems) // private var seasoningItems = mutableListOf<SeasoningEntity>()
} // private fun addGridItemListener() {
} // binding.include.root.forEach { child ->
// child.clickWithDebounce {
private fun initConfigData() { // val sort = child.tag.toString().toInt()
repeat(12) { num -> // val entity = seasoningItems.firstOrNull { it.sort == sort } ?: SeasoningEntity()
val firstOne = seasoningItems.firstOrNull { it.sort == num } // clickGridItem(sort, entity)
if (firstOne == null) { // }
seasoningItems.add(SeasoningEntity().also { it.sort = num }) // }
} // }
} //
} // val detector = MultiClickDetector(targetCount = 10, intervalMs = 800)
//
private fun setGridData(list: MutableList<SeasoningEntity>) { // private fun defaultDataSettingDialog() {
Log.d(TAG, "setGridData: ${list.toJsonString()}") // CommonDialog(this)
val gridLayout = binding.include.root // .setTitle("温馨提示")
list.forEach { entity -> // .setContent("您好,使用默认配置作为您的调料数据,则已有配置将被清除,确认吗?")
val tag = entity.sort.toString() // .setNegativeButton("取消")
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag) // .setPositiveButton("确认") { resetList() }
TextCellAdapter.loadLayout(frameLayout, entity) // .setOnDismissCallback { hideStatusBar() }
} // .show()
} // }
//
private fun updateGridData(entity: SeasoningEntity) { // private fun resetList() {
val gridLayout = binding.include.root // runCatching {
val tag = entity.sort.toString() // val record = JsonAssetsLoader.parseJsonFromAssets<ResetReasoningRecord>(
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag) // this,
TextCellAdapter.loadLayout(frameLayout, entity) // "default_seasoning_list.json"
} // )
//// val weightArray = WeightUtil.weightArray
private fun clickGridItem(sort: Int, entity: SeasoningEntity) { // appViewModel.clearAllSeasoning {
val currentAddress = AddressUtil.getWeighAddressArray().get(sort) // record?.list?.forEach { entity ->
// val seasoningEntity = list.first{it.sort == sort} // entity.useWeight = weightArray[addressArray[entity.sort]].toDouble()
SeasoningSearchDialog( // appViewModel.saveSeasoning(entity) {
activity = this, // updateGridData(entity)
weighIndex = sort, // }
weighAddress = currentAddress, // }
clickName = entity.goodsName //// loadSeasoning()
) { item -> // }
syncItem(entity, item) // }.onFailure { it.printStackTrace() }
//3-调料 // }
entity.materialType = 3 //
entity.sort = sort // private fun initViewModel() {
saveSeasoning(entity) { // val db = BaseApp.instance!!.database
val tag = sort.toString() // val factory =
val gridLayout = binding.include.root // AppFactory(AppRepository(db.appDao()))
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag) // appViewModel =
TextCellAdapter.loadLayout(frameLayout, entity) // ViewModelProvider(this, factory)[AppViewModel::class.java]
} // }
}.show() //
} // private fun loadSeasoning() {
// appViewModel.loadSeasoning {
private fun syncItem(oldItem: SeasoningEntity, newItem: SeasoningEntity) { // seasoningItems.clear()
oldItem.run { // seasoningItems.addAll(it)
goodsId = newItem.goodsId // initConfigData()
goodsName = newItem.goodsName // setGridData(seasoningItems)
goodsOrRelationCode = newItem.goodsOrRelationCode // }
relateionType = newItem.relateionType // }
materialType = newItem.materialType //
allEdible = newItem.allEdible // private fun initConfigData() {
useWeight = newItem.useWeight // repeat(12) { num ->
popularName = newItem.popularName // val firstOne = seasoningItems.firstOrNull { it.sort == num }
canteenId = newItem.canteenId // if (firstOne == null) {
relateionType_dictText = newItem.relateionType_dictText // seasoningItems.add(SeasoningEntity().also { it.sort = num })
// }
foodId = newItem.foodId // }
sort = newItem.sort // }
} //
} // private fun setGridData(list: MutableList<SeasoningEntity>) {
// Log.d(TAG, "setGridData: ${list.toJsonString()}")
private fun loadQualitySpan(isClicked: Boolean = false, isEnable: Boolean = true) { // val gridLayout = binding.include.root
binding.rbModeQuality.text = // list.forEach { entity ->
getModeTextSpan( // val tag = entity.sort.toString()
topText = modeList[2].modeName, // val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
bottomText = modeList[2].modeDesc, // TextCellAdapter.loadLayout(frameLayout, entity)
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4", // }
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4" // }
) //
} // private fun updateGridData(entity: SeasoningEntity) {
// val gridLayout = binding.include.root
private fun loadSamplingSpan(isClicked: Boolean = false, isEnable: Boolean = true) { // val tag = entity.sort.toString()
binding.rbModeSampling.text = // val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
getModeTextSpan( // TextCellAdapter.loadLayout(frameLayout, entity)
topText = modeList[1].modeName, // }
bottomText = modeList[1].modeDesc, //
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4", // private fun clickGridItem(sort: Int, entity: SeasoningEntity) {
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4" // val currentAddress = AddressUtil.getWeighAddressArray().get(sort)
) //// val seasoningEntity = list.first{it.sort == sort}
} // SeasoningSearchDialog(
// activity = this,
private fun loadCookSpan(isClicked: Boolean = false, isEnable: Boolean = true) { // weighIndex = sort,
binding.rbModeCook.text = // weighAddress = currentAddress,
getModeTextSpan( // clickName = entity.goodsName
topText = modeList[0].modeName, // ) { item ->
bottomText = modeList[0].modeDesc, // syncItem(entity, item)
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4", // //3-调料
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4" // entity.materialType = 3
) // entity.sort = sort
} // saveSeasoning(entity) {
// val tag = sort.toString()
private fun getModeTextSpan( // val gridLayout = binding.include.root
topText: String, // val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
topColor: String, // TextCellAdapter.loadLayout(frameLayout, entity)
bottomText: String, // }
bottomColor: String // }.show()
): SpannableStringBuilder { // }
//
// private fun syncItem(oldItem: SeasoningEntity, newItem: SeasoningEntity) {
return buildSpannableString { // oldItem.run {
appendText( // goodsId = newItem.goodsId
topText, // goodsName = newItem.goodsName
ForegroundColorSpan(topColor.toColorInt()), // goodsOrRelationCode = newItem.goodsOrRelationCode
StyleSpan(Typeface.BOLD), // relateionType = newItem.relateionType
AbsoluteSizeSpan(36, true), // materialType = newItem.materialType
LineHeightSpan { text, start, end, spanstartv, v, fm -> // allEdible = newItem.allEdible
fm.descent += 10.dp // 增加行间距 // useWeight = newItem.useWeight
} // popularName = newItem.popularName
) // canteenId = newItem.canteenId
append("\n") // relateionType_dictText = newItem.relateionType_dictText
appendText( //
bottomText, // foodId = newItem.foodId
ForegroundColorSpan(bottomColor.toColorInt()), // sort = newItem.sort
AbsoluteSizeSpan(26, true) // }
) // }
} //
} // private fun loadQualitySpan(isClicked: Boolean = false, isEnable: Boolean = true) {
// binding.rbModeQuality.text =
fun saveSeasoning(entity: SeasoningEntity, action: () -> Unit = {}) { // getModeTextSpan(
appViewModel.saveSeasoning(entity) { // topText = modeList[2].modeName,
action() // bottomText = modeList[2].modeDesc,
toast("保存成功") // topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
} // bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
} // )
// }
} //
// private fun loadSamplingSpan(isClicked: Boolean = false, isEnable: Boolean = true) {
// binding.rbModeSampling.text =
// getModeTextSpan(
// topText = modeList[1].modeName,
// bottomText = modeList[1].modeDesc,
// topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
// bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
// )
// }
//
// private fun loadCookSpan(isClicked: Boolean = false, isEnable: Boolean = true) {
// binding.rbModeCook.text =
// getModeTextSpan(
// topText = modeList[0].modeName,
// bottomText = modeList[0].modeDesc,
// topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
// bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
// )
// }
//
// private fun getModeTextSpan(
// topText: String,
// topColor: String,
// bottomText: String,
// bottomColor: String
// ): SpannableStringBuilder {
//
//
// return buildSpannableString {
// appendText(
// topText,
// ForegroundColorSpan(topColor.toColorInt()),
// StyleSpan(Typeface.BOLD),
// AbsoluteSizeSpan(36, true),
// LineHeightSpan { text, start, end, spanstartv, v, fm ->
// fm.descent += 10.dp // 增加行间距
// }
// )
// append("\n")
// appendText(
// bottomText,
// ForegroundColorSpan(bottomColor.toColorInt()),
// AbsoluteSizeSpan(26, true)
// )
// }
// }
//
// fun saveSeasoning(entity: SeasoningEntity, action: () -> Unit = {}) {
// appViewModel.saveSeasoning(entity) {
// action()
// toast("保存成功")
// }
// }
//
//}
@@ -107,7 +107,7 @@ class HomeActivity : BaseActivity() {
modeDesc = "菜品快速制作,记录熟重", modeDesc = "菜品快速制作,记录熟重",
modeIconId = R.drawable.ic_mode_cook, modeIconId = R.drawable.ic_mode_cook,
onClick = { onClick = {
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 0) SpTool.cookMode = 0
startActivity<SelectDishActivity>() startActivity<SelectDishActivity>()
finish() finish()
}) })
@@ -118,7 +118,7 @@ class HomeActivity : BaseActivity() {
modeDesc = "菜品快速制作,记录熟重", modeDesc = "菜品快速制作,记录熟重",
modeIconId = R.drawable.ic_mode_sampling, modeIconId = R.drawable.ic_mode_sampling,
onClick = { onClick = {
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 1) SpTool.cookMode = 1
goSampling() goSampling()
}) })
) )
@@ -83,8 +83,7 @@ class InitActivity : BaseActivity() {
return@launch return@launch
} }
// 主设备:走原有路由逻辑 // 主设备:走原有路由逻辑
val launchPageType = SpTool.getInt(SpTool.LAUNCH_PAGE_TYPE, -1) when (SpTool.cookMode) {
when (launchPageType) {
0 -> { 0 -> {
startActivity<SelectDishActivity>() startActivity<SelectDishActivity>()
} }
@@ -231,7 +231,7 @@ class SettingActivity : BaseActivity() {
} }
private val fragmentList = mutableListOf<Fragment>().apply { private val fragmentList = mutableListOf<Fragment>().apply {
add(DeviceConfigFragment.newInstance()) add(DeviceConfigFragment())
add(SeasoningConfigFragment()) add(SeasoningConfigFragment())
add(CollectFragment()) add(CollectFragment())
} }
@@ -51,21 +51,11 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
companion object { companion object {
const val TAG = "DeviceConfigFragment" const val TAG = "DeviceConfigFragment"
const val COOK_MODE = "cookMode"
val modeList = listOf<ModeBean>( val modeList = listOf<ModeBean>(
ModeBean("制作模式", "菜品快速制作,记录熟重"), ModeBean("制作模式", "菜品快速制作,记录熟重"),
ModeBean("采样模式", "菜品快速制作,记录熟重"), ModeBean("采样模式", "菜品快速制作,记录熟重"),
ModeBean("品控模式", "菜品快速制作,记录熟重") ModeBean("品控模式", "菜品快速制作,记录熟重")
) )
fun newInstance(cookMode: Int = 0): DeviceConfigFragment {
return DeviceConfigFragment().apply {
arguments = Bundle().apply {
putInt(COOK_MODE, cookMode)
}
}
}
} }
data class ModeBean( data class ModeBean(
@@ -75,7 +65,6 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
// private lateinit var appViewModel: AppViewModel // private lateinit var appViewModel: AppViewModel
private var cookMode: Int = 0
private val weightArray = SparseArray<Double>() private val weightArray = SparseArray<Double>()
private val addressArray = AddressUtil.getWeighAddressArray() private val addressArray = AddressUtil.getWeighAddressArray()
private var seasoningItems = mutableListOf<SeasoningEntity>() private var seasoningItems = mutableListOf<SeasoningEntity>()
@@ -89,7 +78,6 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
} }
override fun initialize(){ override fun initialize(){
cookMode = arguments?.getInt(COOK_MODE, 0) ?: 0
initViewModel() initViewModel()
initUI() initUI()
// addWeighListener() // addWeighListener()
@@ -111,15 +99,15 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
*/ */
private fun initUI() { private fun initUI() {
loadQualitySpan(isEnable = false) loadQualitySpan(isEnable = false)
when (cookMode) { when (SpTool.cookMode) {
1 -> { 0 -> {
binding.rbModeCook.isChecked = true binding.rbModeCook.isChecked = true
binding.rbModeSampling.isChecked = false binding.rbModeSampling.isChecked = false
loadCookSpan(isClicked = true) loadCookSpan(isClicked = true)
loadSamplingSpan() loadSamplingSpan()
} }
2 -> { 1 -> {
binding.rbModeCook.isChecked = false binding.rbModeCook.isChecked = false
binding.rbModeSampling.isChecked = true binding.rbModeSampling.isChecked = true
loadCookSpan() loadCookSpan()
@@ -135,7 +123,7 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
} }
binding.rbModeCook.setOnClickListener { binding.rbModeCook.setOnClickListener {
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 0) SpTool.cookMode = 0
binding.rbModeCook.isChecked = true binding.rbModeCook.isChecked = true
binding.rbModeSampling.isChecked = false binding.rbModeSampling.isChecked = false
loadCookSpan(isClicked = true) loadCookSpan(isClicked = true)
@@ -146,7 +134,7 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
activity?.finish() activity?.finish()
} }
binding.rbModeSampling.setOnClickListener { binding.rbModeSampling.setOnClickListener {
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 1) SpTool.cookMode = 1
binding.rbModeCook.isChecked = false binding.rbModeCook.isChecked = false
binding.rbModeSampling.isChecked = true binding.rbModeSampling.isChecked = true
loadCookSpan() loadCookSpan()
@@ -2,21 +2,86 @@ package com.shuwei.dish.match.ui.fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.flexbox.AlignItems
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager
import com.shuwei.dish.match.adapter.Seasoning18GridAdapter
import com.shuwei.dish.match.adapter.Seasoning22GridAdapter
import com.shuwei.dish.match.base.BaseFragment import com.shuwei.dish.match.base.BaseFragment
import com.shuwei.dish.match.databinding.FragmentSeasoningConfigBinding import com.shuwei.dish.match.databinding.FragmentSeasoningConfigBinding
import com.shuwei.dish.match.ui.SettingActivity import com.shuwei.dish.match.ui.SettingActivity
import com.shuwei.dish.match.utils.ext.dp
class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() { class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
override fun inflateBinding( override fun inflateBinding(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup? container: ViewGroup?
) = FragmentSeasoningConfigBinding.inflate(inflater, container, false) ) = FragmentSeasoningConfigBinding.inflate(inflater, container, false)
private lateinit var settingActivity: SettingActivity private lateinit var settingActivity: SettingActivity
// private lateinit var appViewModel: AppViewModel
private val adapter22 by lazy { buildAdapter22() }
private val adapter18 by lazy { Seasoning18GridAdapter() }
override fun initialize() { override fun initialize() {
settingActivity = activity as SettingActivity settingActivity = activity as SettingActivity
// initViewModel()
setupRecyclerViews()
loadData()
} }
// /** 初始化 ViewModel */
// private fun initViewModel() {
// val factory = AppFactory(AppRepository(BaseApp.instance!!.database.appDao()))
// appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
// }
/** 构建上层(22格)Adapter,需要先计算格子尺寸 */
private fun buildAdapter22(): Seasoning22GridAdapter {
val usable = resources.displayMetrics.widthPixels - 8 * 4.dp - 10.dp
val smallSize = usable / 9
val largeSize = (usable - smallSize * 6) / 2
return Seasoning22GridAdapter(largeSize, smallSize)
}
/** 配置两个 RecyclerView */
private fun setupRecyclerViews() {
// 上层:FlexboxLayoutManager,仿 MasterScaleActivity 中 Scale22VH 的布局方式
// rvTop 高度 = 小格子尺寸 * 3行 + 3 * 间距,与 Scale22VH 保持一致
val screenWidth = resources.displayMetrics.widthPixels
val usable = screenWidth - 8 * 4.dp - 10.dp
val smallSize = usable / 9
val rvTopHeight = smallSize * 3 + 3 * 4.dp
binding.rvTop.apply {
layoutParams = layoutParams.also { it.height = rvTopHeight }
layoutManager = FlexboxLayoutManager(requireContext()).apply {
flexDirection = FlexDirection.COLUMN
flexWrap = FlexWrap.WRAP
alignItems = AlignItems.FLEX_START
}
itemAnimator = null
adapter = adapter22
}
// 下层:GridLayoutManager 6列,仿 Scale18VH
binding.rvBottom.apply {
layoutManager = GridLayoutManager(requireContext(), 6)
itemAnimator = null
adapter = adapter18
}
}
/** 加载默认空数据,使两个列表完整展示所有格子 */
private fun loadData() {
adapter22.update(emptyList())
adapter18.update(emptyList())
// appViewModel.loadSeasoning { list ->
// adapter22.update(list ?: emptyList())
// adapter18.update(list ?: emptyList())
// }
}
} }
@@ -31,4 +31,10 @@ object SpTool {
fun getBoolean(key: String, defValue: Boolean = false): Boolean { fun getBoolean(key: String, defValue: Boolean = false): Boolean {
return pref.getBoolean(key, defValue) return pref.getBoolean(key, defValue)
} }
var cookMode: Int
get() = getInt(LAUNCH_PAGE_TYPE, -1)
set(value) {
put(LAUNCH_PAGE_TYPE, value)
}
} }
@@ -1,7 +1,42 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/bg_color"> android:background="@color/bg_color">
</androidx.constraintlayout.widget.ConstraintLayout> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上层"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@color/home_title"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="6dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下层"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@color/home_title"
android:layout_marginStart="10dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="6dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never" />
</LinearLayout>