diff --git a/app/src/main/java/com/shuwei/dish/match/adapter/FoodListAdapter.kt b/app/src/main/java/com/shuwei/dish/match/adapter/FoodListAdapter.kt index e2126d0..0c2d4fd 100644 --- a/app/src/main/java/com/shuwei/dish/match/adapter/FoodListAdapter.kt +++ b/app/src/main/java/com/shuwei/dish/match/adapter/FoodListAdapter.kt @@ -86,6 +86,8 @@ class FoodListAdapter( return@run } // 非烹饪中,采样模式 + tvDishName.setTextColor(ContextCompat.getColor(holder.itemView.context, R.color.dish_green)) + clBlock.setBackgroundResource(R.drawable.shape_white_fb_15_corners) val realTotalWeight = if (totalWeight > 0.0) totalWeight else foodWeight val showTotalWeight = if (realTotalWeight == 0.0) "-" else df.format(realTotalWeight / 1000.0F) tvDishCount.text = "累计统计:${showTotalWeight}kg(${item.count ?: "-"}次)" diff --git a/app/src/main/java/com/shuwei/dish/match/db/DbViewModel.kt b/app/src/main/java/com/shuwei/dish/match/db/DbViewModel.kt index a2702a7..b8b364e 100644 --- a/app/src/main/java/com/shuwei/dish/match/db/DbViewModel.kt +++ b/app/src/main/java/com/shuwei/dish/match/db/DbViewModel.kt @@ -48,6 +48,20 @@ class DbViewModel : ViewModel() { } } + /** + * 查询本地烹饪中数据(回调版本),结果通过 onResult 直接回调,不经过 StateFlow + * 适合不需要跨生命周期持续监听的一次性查询场景 + */ + fun getCookFoodListWithCallback( + cookMode: Int, + dinnerType: String = "0", + onResult: (MutableList?) -> Unit + ) { + viewModelScope.launch { + onResult(rep.getCookFoodList(cookMode, dinnerType)) + } + } + /** * 直接返回本地烹饪中数据,供需要串行等待结果的场景使用(如先查库再发网络请求) */ @@ -115,6 +129,17 @@ class DbViewModel : ViewModel() { } } + /** + * 接口提交成功后删除本地菜品草稿(异步版本,绑定 viewModelScope) + * 与 [markSubmittedAndDelete] 的区别:不是 suspend,内部用 viewModelScope 启动协程, + * 不受调用方 Activity 生命周期影响,适合 singleTask 跳转前触发删除的场景 + */ + fun markSubmittedAndDeleteAsync(cookMode: Int, foodId: String, dinnerType: String) { + viewModelScope.launch { + markSubmittedAndDelete(cookMode, foodId, dinnerType) + } + } + /** * 接口提交成功后删除本地菜品草稿 * 与 [deleteCookFoodAndGoods] 的区别:主表 submitState 会被置 1,便于审计区分手动删除与接口删除 diff --git a/app/src/main/java/com/shuwei/dish/match/dialog/CommonDialog.kt b/app/src/main/java/com/shuwei/dish/match/dialog/CommonDialog.kt index c198ce7..e841f33 100644 --- a/app/src/main/java/com/shuwei/dish/match/dialog/CommonDialog.kt +++ b/app/src/main/java/com/shuwei/dish/match/dialog/CommonDialog.kt @@ -26,10 +26,12 @@ open class CommonDialog( private var negativeText = "取消" private var positiveText = "确认" private var neutralText: String? = null + private var singleText: String? = null private var negativeClick: (() -> Unit)? = null // 返回 true 时关闭弹窗,返回 false 时保持弹窗显示(用于校验不通过的场景) private var positiveClick: (() -> Boolean)? = null private var neutralClick: (() -> Unit)? = null + private var singleClick: (() -> Unit)? = null private var dismissCallback: (() -> Unit)? = null // 待添加到 llContent 的自定义 View,在 onCreate 后挂载 private var pendingContentView: View? = null @@ -69,6 +71,12 @@ open class CommonDialog( neutralClick = onClick } + /** 设置单按钮文字及点击回调,调用后自动切换为单按钮布局(优先级最高) */ + fun setSingleButton(text: String, onClick: (() -> Unit)? = null): CommonDialog = apply { + singleText = text + singleClick = onClick + } + /** 设置弹窗消失回调 */ fun setOnDismissCallback(callback: () -> Unit): CommonDialog = apply { dismissCallback = callback @@ -130,6 +138,12 @@ open class CommonDialog( if (positiveClick?.invoke() != false) dismiss() } + // 单按钮点击事件 + binding.btnSingle.setOnClickListener { + singleClick?.invoke() + dismiss() + } + setOnDismissListener { dismissCallback?.invoke() } // 挂载自定义内容 View,并执行 tvContent 的灵活控制回调 @@ -148,10 +162,15 @@ open class CommonDialog( binding.tvContent.visibility = if (contentText.isNullOrEmpty()) View.GONE else View.VISIBLE val hasThreeButtons = !neutralText.isNullOrEmpty() - binding.layoutButtonsHorizontal.visibility = if (hasThreeButtons) View.GONE else View.VISIBLE + val hasSingleButton = !singleText.isNullOrEmpty() + binding.btnSingle.visibility = if (hasSingleButton) View.VISIBLE else View.GONE + binding.layoutButtonsHorizontal.visibility = if (!hasSingleButton && !hasThreeButtons) View.VISIBLE else View.GONE binding.layoutButtonsVertical.visibility = if (hasThreeButtons) View.VISIBLE else View.GONE - if (hasThreeButtons) { + if (hasSingleButton) { + // 单按钮模式 + binding.btnSingle.text = singleText + } else if (hasThreeButtons) { // 3按钮模式:顶部=取消,中间=中立,底部=确认 binding.btnTop.text = negativeText binding.btnMiddle.text = neutralText diff --git a/app/src/main/java/com/shuwei/dish/match/dialog/FoodSearchDialog.kt b/app/src/main/java/com/shuwei/dish/match/dialog/FoodSearchDialog.kt index 6de860a..bc782ca 100644 --- a/app/src/main/java/com/shuwei/dish/match/dialog/FoodSearchDialog.kt +++ b/app/src/main/java/com/shuwei/dish/match/dialog/FoodSearchDialog.kt @@ -57,7 +57,7 @@ class FoodSearchDialog( private val adapter = FoodAdapter(list).apply { isStateViewEnable = true setOnDebouncedItemClick { _, _, position -> - val item = list[position] + val item = list.getOrNull(position) ?: return@setOnDebouncedItemClick // 弹出净材种类单选弹窗,确认后再回调并关闭弹窗 showRawMaterialsDialog( context = activity, diff --git a/app/src/main/java/com/shuwei/dish/match/dialog/SeasoningSelectDialog.kt b/app/src/main/java/com/shuwei/dish/match/dialog/SeasoningSelectDialog.kt index d50eb53..0f2341c 100644 --- a/app/src/main/java/com/shuwei/dish/match/dialog/SeasoningSelectDialog.kt +++ b/app/src/main/java/com/shuwei/dish/match/dialog/SeasoningSelectDialog.kt @@ -52,10 +52,11 @@ class SeasoningSelectDialog( private val adapter = SeasoningSearchAdapter(list).apply { isStateViewEnable = true setOnItemClickListener { _, v, position -> - list[position].isClicked = true + val item = list.getOrNull(position) ?: return@setOnItemClickListener + item.isClicked = true notifyItemChanged(position) v.postDelayed({ - onItemSelected(list[position]) + onItemSelected(item) dismiss() }, 300) } diff --git a/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt b/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt index 5e86893..7510e79 100644 --- a/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt +++ b/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt @@ -122,6 +122,21 @@ class NetViewModel( } } + /** + * 查询采样数据列表(回调版本),结果通过 onResult 直接回调,不经过 StateFlow + * 适合不需要跨生命周期持续监听的一次性查询场景 + */ + fun getSamplingListWithCallback( + param: MutableMap, + onLoading: () -> Unit = {}, + onResult: (UiState?>) -> Unit + ) { + viewModelScope.launch { + onLoading() + onResult(repository.getSamplingList(param)) + } + } + /** * 查询物品信息列表的 UI 状态流(食材/调料共用),UI 层通过 collect 监听 */ diff --git a/app/src/main/java/com/shuwei/dish/match/ui/CollectedFoodActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/CollectedFoodActivity.kt index bfba96c..ea98732 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/CollectedFoodActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/CollectedFoodActivity.kt @@ -27,6 +27,7 @@ import com.shuwei.dish.match.utils.ext.gone import com.shuwei.dish.match.utils.ext.toast import com.shuwei.dish.match.utils.ext.visible import kotlinx.coroutines.launch +import kotlin.collections.getOrNull /** * 已采集食材列表页面 @@ -45,7 +46,8 @@ class CollectedFoodActivity : BaseActivity() { isStateViewEnable = true // 点击删除按钮,移除对应食材 addOnItemChildClickListener(R.id.ivDelete) { _, _, position -> - showDeleteDialog(foodList[position].foodName) + val item = foodList.getOrNull(position) ?: return@addOnItemChildClickListener + showDeleteDialog(item.foodName) } setOnItemClickListener { _, _, _ -> hideKeyboard() diff --git a/app/src/main/java/com/shuwei/dish/match/ui/FoodRecognizeActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/FoodRecognizeActivity.kt index 165aa88..5d6d754 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/FoodRecognizeActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/FoodRecognizeActivity.kt @@ -135,7 +135,7 @@ class FoodRecognizeActivity : BaseActivity() { private val adapter = FoodAdapter(list).apply { setOnItemClickListener { _, _, position -> // rawMaterialsRemind(position) - val item = list[position] + val item = list.getOrNull(position) ?: return@setOnItemClickListener list.forEachIndexed { i, it -> it.isClicked = (i == position) } // 点击选择时记录当前秤重量 item.useWeight = currentWeight @@ -146,7 +146,7 @@ class FoodRecognizeActivity : BaseActivity() { } private fun rawMaterialsRemind(position: Int) { - val item = list[position] + val item = list.getOrNull(position) ?: return // 弹出净材种类单选弹窗,确认后再选中该食材 showRawMaterialsDialog( context = this@FoodRecognizeActivity, @@ -514,8 +514,10 @@ class FoodRecognizeActivity : BaseActivity() { if (unstableDialog == null) { unstableDialog = CommonDialog(this) .setTitle("提示") - .setContent("数据不稳定,请重新放置食材后再取走") - .setPositiveButton("确认") + .setContent("秤数据不稳定,请放置食材进行重新识别") + .setSingleButton("确认") { + finishWithResult(true) + } } unstableDialog?.show() return diff --git a/app/src/main/java/com/shuwei/dish/match/ui/FoodSearchActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/FoodSearchActivity.kt index 1b746e3..e442bde 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/FoodSearchActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/FoodSearchActivity.kt @@ -25,6 +25,7 @@ import com.shuwei.dish.match.utils.ext.toast import com.shuwei.dish.match.utils.ext.visible import java.io.Serializable import kotlinx.coroutines.launch +import kotlin.collections.getOrNull /** * 菜品搜索页面 @@ -47,15 +48,16 @@ class FoodSearchActivity : BaseActivity() { Food2Adapter(list).apply { isStateViewEnable = true setOnItemClickListener { adapter, view, position -> + var jumpItem = list.getOrNull(position) ?: return@setOnItemClickListener if (SpTool.cookMode == 0) { - val jumpItem = list[position].also { it.dinnerType = dinnerType } + jumpItem.dinnerType = dinnerType startActivity { putExtra(PrepareFoodActivity.FOOD_ITEM, jumpItem as Serializable) } return@setOnItemClickListener } setResult(RESULT_OK, Intent().apply { - putExtra(FOOD_ITEM, list[position] as Serializable) + putExtra(FOOD_ITEM, jumpItem as Serializable) }) finish() } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/HomeActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/HomeActivity.kt index e6b3b8f..4875d99 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/HomeActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/HomeActivity.kt @@ -15,6 +15,7 @@ import com.shuwei.dish.match.utils.SpTool import com.shuwei.dish.match.utils.ext.startActivity import com.shuwei.dish.match.utils.ext.toast import kotlinx.coroutines.launch +import kotlin.collections.getOrNull /** * 主页,包括三种模式:制作模式、采样模式、品控模式 @@ -97,7 +98,7 @@ class HomeActivity : BaseActivity() { private val modeAdapter by lazy { HomeModeAdapter(modeList).apply { addOnItemChildClickListener(R.id.layoutCard) { adapter, view, position -> - modeList[position].onClick?.invoke() + modeList.getOrNull(position)?.onClick?.invoke() } } } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/PrepareFoodActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/PrepareFoodActivity.kt index 097da0e..91a2424 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/PrepareFoodActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/PrepareFoodActivity.kt @@ -146,10 +146,10 @@ class PrepareFoodActivity : BaseActivity() { if (address == AddressUtil.ONE && state == WeightUtil.STATE_STABLE) { runOnUiThread { // 首次收到稳定读数时,将其作为初始值(去皮基准) - if (!initialWeightReady) { - initialWeight = weight - initialWeightReady = true - } +// if (!initialWeightReady) { +// initialWeight = weight +// initialWeightReady = true +// } // 净重 = 秤读数 - 初始读数 val netWeight = weight - initialWeight binding.tvShowWeight.run { @@ -227,7 +227,7 @@ class PrepareFoodActivity : BaseActivity() { private var initialWeight = 0.0 /** 初始读数是否已从秤获取 */ - private var initialWeightReady = false +// private var initialWeightReady = false /** * 重量稳定时触发菜品识别 @@ -413,8 +413,8 @@ class PrepareFoodActivity : BaseActivity() { notifyDataSetChanged() } addOnItemChildClickListener(R.id.ivClearIcon) { _, _, position -> - Log.d(TAG, "onFoodItemClick: ${list[position].toJsonString()}") - val item = list[position] + val item = list.getOrNull(position) ?:return@addOnItemChildClickListener + Log.d(TAG, "onFoodItemClick: ${item.toJsonString()}") if (item.isOriginalData) { // 无重量信息时转为 item 整体点击(触发选中效果) if (item.useWeight == null || item.useWeight == 0.0) { diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SamplingModeActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SamplingModeActivity.kt index f190a4e..05597e0 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SamplingModeActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SamplingModeActivity.kt @@ -3,13 +3,12 @@ package com.shuwei.dish.match.ui import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup import android.widget.FrameLayout import androidx.activity.addCallback -import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.LinearLayoutManager import com.shuwei.dish.match.R import com.shuwei.dish.match.adapter.FoodListAdapter @@ -49,77 +48,10 @@ class SamplingModeActivity : BaseActivity() { setHeaderBackground() initRecyclerView() addViewListener() - initObserver() requestData(true) onBackPressedDispatcher.addCallback(this) { } } - /** - * 收集 cookFoodListState,将本地烹饪中数据渲染到列表 - */ - private fun initObserver() { - lifecycleScope.launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - appViewModel.cookFoodListState.collect { cookFoodEntities -> - if (binding.dishRadioGroup.checkedRadioButtonId != R.id.rbSamplingCooking) return@collect - delayDismissLoading() - if (cookFoodEntities.isNullOrEmpty()) { - loadEmptyView() - return@collect - } - val tempList = mutableListOf() - cookFoodEntities.sortedByDescending { DateTimeUtil.convert(dateStr = it.createTime) } - .forEach { entity -> - tempList.add(FoodRecord().apply { - foodId = entity.foodId - foodName = entity.foodName - cookMode = 1 - isCooking = true - dinnerType = entity.dinnerType ?: "0" - }) - } - list.clear() - list.addAll(tempList) - dishAdapter.notifyDataSetChanged() - finishRefresh() - binding.refreshLayout.run { - setEnableRefresh(false) - setEnableLoadMore(false) - } - } - } - } - lifecycleScope.launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - netViewModel.samplingListState.collect { state -> - when (state) { - is UiState.Loading -> showLoading() - is UiState.Success -> { - if (binding.dishRadioGroup.checkedRadioButtonId != R.id.rbSamplingFinished) { - delayDismissLoading() - return@collect - } - loadDishList(state.data) - } - is UiState.Error -> { - if (binding.dishRadioGroup.checkedRadioButtonId != R.id.rbSamplingFinished) { - delayDismissLoading() - return@collect - } - binding.refreshLayout.setEnableRefresh(true) - toast(state.msg) - finishRefresh() - delayDismissLoading() - if (pageNo == 1) loadEmptyView() - } - is UiState.Idle -> {} - } - } - } - } - } - - private fun setTitleBar() { setTitleBar(titleBarAction = { it.visible() @@ -134,17 +66,43 @@ class SamplingModeActivity : BaseActivity() { }, backAction = { it.gone() }) - - } - - + @SuppressLint("NotifyDataSetChanged") fun getCookFoodList() { - val checkedId = binding.dishRadioGroup.checkedRadioButtonId - if (checkedId == R.id.rbSamplingCooking) { - appViewModel.getCookFoodList(cookMode = 1) - } + //val checkedId = binding.dishRadioGroup.checkedRadioButtonId +// if (checkedId == R.id.rbSamplingCooking) { +// if (binding.rbSamplingCooking.isChecked) { + appViewModel.getCookFoodListWithCallback(cookMode = 1) { cookFoodEntities -> + // 回调期间用户可能已切换 Tab,需再次校验 +// if (binding.dishRadioGroup.checkedRadioButtonId != R.id.rbSamplingCooking) return@getCookFoodListWithCallback + if (binding.rbSamplingCooking.isChecked.not()) return@getCookFoodListWithCallback + delayDismissLoading() + if (cookFoodEntities.isNullOrEmpty()) { + loadEmptyView() + return@getCookFoodListWithCallback + } + val tempList = mutableListOf() + cookFoodEntities.sortedByDescending { DateTimeUtil.convert(dateStr = it.createTime) } + .forEach { entity -> + tempList.add(FoodRecord().apply { + foodId = entity.foodId + foodName = entity.foodName + cookMode = 1 + isCooking = true + dinnerType = entity.dinnerType ?: "0" + }) + } + list.clear() + list.addAll(tempList) + dishAdapter.notifyDataSetChanged() + finishRefresh() + binding.refreshLayout.run { + setEnableRefresh(false) + setEnableLoadMore(false) + } + } +// } } fun deleteCookFoodAndGoods(foodId: String, dinnerType: String, action: () -> Unit) { @@ -157,11 +115,13 @@ class SamplingModeActivity : BaseActivity() { override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) val isConfigPage = intent?.getBooleanExtra(IS_CONFIG_PAGE, false) ?: false + Log.d(TAG, "onNewIntent, isConfigPage=$isConfigPage") if (isConfigPage) { getCookFoodList() return } val isCooking = intent?.getBooleanExtra(IS_COOKING, false) ?: false + Log.d(TAG, "onNewIntent, isCooking=$isCooking") //toast("isCooking=$isCooking") refreshPage(isCooking) } @@ -252,7 +212,8 @@ class SamplingModeActivity : BaseActivity() { } binding.refreshLayout.setOnRefreshListener { pageNo = 1 - if (binding.dishRadioGroup.checkedRadioButtonId == R.id.rbSamplingFinished) { +// if (binding.dishRadioGroup.checkedRadioButtonId == R.id.rbSamplingFinished) { + if (binding.rbSamplingFinished.isChecked) { getSamplingList() } else { finishRefresh() @@ -260,30 +221,41 @@ class SamplingModeActivity : BaseActivity() { } } binding.refreshLayout.setOnLoadMoreListener { - if (binding.dishRadioGroup.checkedRadioButtonId == R.id.rbSamplingFinished) { +// if (binding.dishRadioGroup.checkedRadioButtonId == R.id.rbSamplingFinished) { + if (binding.rbSamplingFinished.isChecked) { getSamplingList() } else { finishRefresh() } } - binding.rbSamplingCooking.setOnClickListener { + binding.rbSamplingCooking.let { + it.setOnClickListener { _-> // Log.d(TAG, "addViewListener: cooking:${binding.rbSamplingCooking.isChecked}") - if (it.tag == true) { - return@setOnClickListener +// if (it.tag == true) { + if (it.isChecked) { + return@setOnClickListener + } + binding.rbSamplingCooking.isChecked = true + binding.rbSamplingFinished.isChecked = false + binding.rbSamplingCooking.tag = binding.rbSamplingCooking.isChecked + binding.rbSamplingFinished.tag = binding.rbSamplingFinished.isChecked + requestData(true) } - requestData(true) - binding.rbSamplingCooking.tag = binding.rbSamplingCooking.isChecked - binding.rbSamplingFinished.tag = binding.rbSamplingFinished.isChecked } - binding.rbSamplingFinished.setOnClickListener { + binding.rbSamplingFinished.let { + it.setOnClickListener { _-> // Log.d(TAG, "addViewListener: finish:${binding.rbSamplingFinished.isChecked}") - if (it.tag == true) { - return@setOnClickListener +// if (it.tag == true) { + if (it.isChecked) { + return@setOnClickListener + } + binding.rbSamplingCooking.isChecked = false + binding.rbSamplingFinished.isChecked = true + binding.rbSamplingCooking.tag = binding.rbSamplingCooking.isChecked + binding.rbSamplingFinished.tag = binding.rbSamplingFinished.isChecked + requestData(false) } - requestData(false) - binding.rbSamplingCooking.tag = binding.rbSamplingCooking.isChecked - binding.rbSamplingFinished.tag = binding.rbSamplingFinished.isChecked } } @@ -292,13 +264,39 @@ class SamplingModeActivity : BaseActivity() { @SuppressLint("NotifyDataSetChanged") fun getSamplingList() { - netViewModel.getSamplingList( + netViewModel.getSamplingListWithCallback( param = mutableMapOf( "pageNum" to pageNo, "pageSize" to pageSize, "placeId" to BaseApp.canteenId - ) - ) + ), + onLoading = { showLoading() } + ) { state -> + when (state) { + is UiState.Success -> { + // 回调期间用户可能已切换 Tab,需再次校验 +// if (binding.dishRadioGroup.checkedRadioButtonId != R.id.rbSamplingFinished) { + if (binding.rbSamplingFinished.isChecked.not()) { + delayDismissLoading() + return@getSamplingListWithCallback + } + loadDishList(state.data) + } + is UiState.Error -> { +// if (binding.dishRadioGroup.checkedRadioButtonId != R.id.rbSamplingFinished) { + if (binding.rbSamplingFinished.isChecked.not()) { + delayDismissLoading() + return@getSamplingListWithCallback + } + binding.refreshLayout.setEnableRefresh(true) + toast(state.msg) + finishRefresh() + delayDismissLoading() + if (pageNo == 1) loadEmptyView() + } + else -> {} + } + } } private fun finishRefresh() { @@ -336,18 +334,22 @@ class SamplingModeActivity : BaseActivity() { //dishAdapter.setStateViewLayout(requireContext(), R.layout-sw800dp.layout_empty_view) binding.refreshLayout.run { - setEnableRefresh(binding.dishRadioGroup.checkedRadioButtonId == R.id.rbSamplingFinished) +// setEnableRefresh(binding.dishRadioGroup.checkedRadioButtonId == R.id.rbSamplingFinished) + setEnableRefresh(binding.rbSamplingFinished.isChecked) setEnableLoadMore(false) } } fun refreshPage(isCooking: Boolean) { - val checkedId = binding.dishRadioGroup.checkedRadioButtonId - if (checkedId == R.id.rbSamplingFinished) { +// val checkedId = binding.dishRadioGroup.checkedRadioButtonId +// if (checkedId == R.id.rbSamplingFinished) { + if (binding.rbSamplingFinished.isChecked) { //当前是已采样 if (isCooking) { //需要切换到烹饪中 - binding.dishRadioGroup.check(R.id.rbSamplingCooking) + //binding.dishRadioGroup.check(R.id.rbSamplingCooking) + binding.rbSamplingCooking.isChecked = true + binding.rbSamplingFinished.isChecked = false requestData(true) return } @@ -358,7 +360,9 @@ class SamplingModeActivity : BaseActivity() { //当前是烹饪中 if (isCooking.not()) { //需要切换到已采样 - binding.dishRadioGroup.check(R.id.rbSamplingFinished) +// binding.dishRadioGroup.check(R.id.rbSamplingFinished) + binding.rbSamplingCooking.isChecked = false + binding.rbSamplingFinished.isChecked = true requestData(false) return } @@ -366,21 +370,17 @@ class SamplingModeActivity : BaseActivity() { requestData(true) } - @SuppressLint("NotifyDataSetChanged") fun refreshLocalData() { showLoading() - appViewModel.resetCookFoodList() getCookFoodList() } private fun requestData(isCooking: Boolean) { + list.clear() + dishAdapter.notifyDataSetChanged() if (isCooking) { - // 清除上次网络请求的残留状态 - netViewModel.resetSamplingListState() refreshLocalData() } else { - // 同理,清除本地数据残留状态 - appViewModel.resetCookFoodList() pageNo = 1 getSamplingList() } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt index b2eeab2..bad0d72 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt @@ -106,7 +106,7 @@ class SubmitFoodActivity : BaseActivity() { private var initWeight: Double = 0.0 /** initWeight 是否已完成初始化 */ - private var initWeightSet: Boolean = false +// private var initWeightSet: Boolean = false @Suppress("unchecked_cast", "DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { @@ -340,10 +340,10 @@ class SubmitFoodActivity : BaseActivity() { WeightUtil.addWeightListener(TAG) { address, _, weight -> if (address == AddressUtil.TWO) { // 首次收到数据时记录初始重量 - if (!initWeightSet) { - initWeight = weight - initWeightSet = true - } +// if (!initWeightSet) { +// initWeight = weight +// initWeightSet = true +// } // 实际净重 = 秤读数 - 初始重量 val netWeight = weight - initWeight cookFoodEntity.foodWeight = netWeight @@ -464,15 +464,15 @@ class SubmitFoodActivity : BaseActivity() { jumpPage(isSamplingData, false) return } - lifecycleScope.launch { - appViewModel.markSubmittedAndDelete( - cookMode = food!!.cookMode, - foodId = food!!.foodId!!, - dinnerType = food!!.dinnerType - ) - dismissLoading() - jumpPage(isSamplingData, false) - } + // 用 viewModelScope 执行删除,不受当前 Activity 生命周期影响 + // singleTask 跳转会销毁本 Activity 并取消 lifecycleScope,导致删除被中断 + appViewModel.markSubmittedAndDeleteAsync( + cookMode = food!!.cookMode, + foodId = food!!.foodId!!, + dinnerType = food!!.dinnerType + ) + dismissLoading() + jumpPage(isSamplingData, false) } private fun jumpPage(isSampling: Boolean, isCooking: Boolean) { diff --git a/app/src/main/java/com/shuwei/dish/match/ui/fragment/FoodListFragment.kt b/app/src/main/java/com/shuwei/dish/match/ui/fragment/FoodListFragment.kt index 2d9d707..01c18b7 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/fragment/FoodListFragment.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/fragment/FoodListFragment.kt @@ -75,7 +75,7 @@ class FoodListFragment : BaseFragment() { } private fun onItemClick(position: Int) { - val item = list[position] + val item = list.getOrNull(position) ?: return if (item.isCooking) { // 烹饪中,跳到称熟重页面 activity.startActivity { @@ -124,12 +124,12 @@ class FoodListFragment : BaseFragment() { } .show() } - // item 点击 - setOnItemClickListener { _, position -> - if (isAdded && isVisible) { - activity.judgeDeviceConfig { onItemClick(position) } - } - } +// // item 点击 +// setOnItemClickListener { _, position -> +// if (isAdded && isVisible) { +// activity.judgeDeviceConfig { onItemClick(position) } +// } +// } adapter = dishAdapter } addViewListener() diff --git a/app/src/main/java/com/shuwei/dish/match/ui/fragment/VectorCollectionFragment.kt b/app/src/main/java/com/shuwei/dish/match/ui/fragment/VectorCollectionFragment.kt index 968eefa..aca77fd 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/fragment/VectorCollectionFragment.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/fragment/VectorCollectionFragment.kt @@ -81,7 +81,7 @@ class VectorCollectionFragment : BaseFragment() // 开启空状态视图能力,否则 stateView 赋值不会生效 isStateViewEnable = true setOnDebouncedItemClick { _, _, position -> - val item = searchList[position] + val item = searchList.getOrNull(position) ?: return@setOnDebouncedItemClick // 弹出净材种类单选弹窗 showRawMaterialsDialog( context = requireContext(), @@ -113,7 +113,7 @@ class VectorCollectionFragment : BaseFragment() private val vectorAdapter: VectorCollectionAdapter by lazy { VectorCollectionAdapter(vectorList).apply { addOnItemChildClickListener(R.id.ivDelete) { _, _, position -> - vectorList[position].let { + vectorList.getOrNull(position)?.let { it.bitmap = null it.imageVector = null it.imageFile = null @@ -121,8 +121,8 @@ class VectorCollectionFragment : BaseFragment() it.isShowCamera = true it.isFinish = false it.uploadSuccess = false + notifyItemChanged(position) } - notifyItemChanged(position) } } } diff --git a/app/src/main/java/com/shuwei/dish/match/utils/CrashHandler.kt b/app/src/main/java/com/shuwei/dish/match/utils/CrashHandler.kt index 922b7ae..f2069a2 100644 --- a/app/src/main/java/com/shuwei/dish/match/utils/CrashHandler.kt +++ b/app/src/main/java/com/shuwei/dish/match/utils/CrashHandler.kt @@ -11,6 +11,7 @@ import android.os.Looper import android.os.Process import android.util.Log import com.shuwei.dish.match.ui.HomeActivity +import com.shuwei.dish.match.ui.InitActivity import java.io.File import java.io.FileOutputStream import java.io.IOException @@ -75,7 +76,7 @@ class CrashHandler private constructor(private val context: Context) : private fun restartApp() { // 延迟1秒后重启应用 Handler(Looper.getMainLooper()).postDelayed({ - val intent = Intent(context, HomeActivity::class.java).apply { + val intent = Intent(context, InitActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } diff --git a/app/src/main/res/layout/activity_sampling_mode.xml b/app/src/main/res/layout/activity_sampling_mode.xml index 2566d8f..8d8b01f 100644 --- a/app/src/main/res/layout/activity_sampling_mode.xml +++ b/app/src/main/res/layout/activity_sampling_mode.xml @@ -6,14 +6,53 @@ android:orientation="vertical" tools:background="@drawable/bg_other_page"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + +