From 634f23a76a155833535846be586231fb375abc46 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Mon, 27 Apr 2026 13:50:56 +0800 Subject: [PATCH] =?UTF-8?q?style(ui):=20=E4=BC=98=E5=8C=96=E9=A3=9F?= =?UTF-8?q?=E7=89=A9=E8=AF=86=E5=88=AB=E7=95=8C=E9=9D=A2=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E5=92=8C=E5=AF=B9=E8=AF=9D=E6=A1=86=E6=A0=87=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将食物照片区域包装在 CardView 中并调整样式 - 为食材列表容器添加滚动指示条功能 - 替换 RecyclerView 的滚动条为自定义指示条 - 更新多个对话框的标题文本以提高一致性 - 在准备烹饪界面添加重量显示文本 - 优化适配器数据更新和列表滚动逻辑 - 防止 StateFlow 重放导致的重复数据加载 - 添加新的滚动条绘制资源文件 --- .../dish/match/ui/CollectedFoodActivity.kt | 2 +- .../dish/match/ui/DishSamplingActivity.kt | 4 +- .../dish/match/ui/FoodRecognizeActivity.kt | 70 ++++++++- .../dish/match/ui/PrepareCookActivity.kt | 22 ++- .../dish/match/ui/SamplingListActivity.kt | 2 +- .../dish/match/ui/SelectDishActivity.kt | 2 +- .../shuwei/dish/match/ui/SettingActivity.kt | 2 +- .../dish/match/ui/SubmitFoodActivity.kt | 6 +- .../scrollbar_thumb_food_recognize.xml | 8 + .../scrollbar_track_food_recognize.xml | 7 + .../res/layout/activity_food_recognize.xml | 148 +++++++++++------- .../main/res/layout/activity_prepare_cook.xml | 10 ++ 12 files changed, 205 insertions(+), 78 deletions(-) create mode 100644 app/src/main/res/drawable/scrollbar_thumb_food_recognize.xml create mode 100644 app/src/main/res/drawable/scrollbar_track_food_recognize.xml 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 18fb7cc..3d4c8a5 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 @@ -65,7 +65,7 @@ class CollectedFoodActivity : BaseActivity() { appendText(" 删除后无法恢复,${separator}确认要删除吗?") } CommonDialog(this) - .setTitle("温馨提示") + .setTitle("删除提示") .setContent(content) .setNegativeButton("取消") .setPositiveButton("确认") { diff --git a/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt index 78b77ff..a8d895e 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt @@ -117,8 +117,8 @@ class DishSamplingActivity : BaseActivity() { private fun saveDataRemindDialog() { CommonDialog(this) - .setTitle("温馨提示") - .setContent("您好,当前页面存在未保存的数据,确认返回吗?") + .setTitle("返回提示") + .setContent("您好,当前页面存在未保存的数据,\n确认返回吗?") .setNegativeButton("取消") .setPositiveButton("确认") { if (pageFrom == HOME) { 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 63e7c0d..93c19fa 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 @@ -6,6 +6,7 @@ import android.os.Bundle import androidx.activity.addCallback import androidx.core.content.IntentCompat import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.shuwei.dish.match.adapter.GoodsInfoSearchAdapter import com.shuwei.dish.match.base.BaseActivity import com.shuwei.dish.match.databinding.ActivityFoodRecognizeBinding @@ -93,6 +94,15 @@ class FoodRecognizeActivity : BaseActivity() { /** 当前待延迟更新的目标重量,避免相同重量重复重置计时器 */ private var pendingWeight = 0.0 + /** 右侧自定义滚动指示条最小高度 */ + private val scrollIndicatorMinHeightPx by lazy { (24 * resources.displayMetrics.density).toInt() } + + private val scrollListener = object : RecyclerView.OnScrollListener() { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + updateScrollIndicator() + } + } + private val adapter = GoodsInfoSearchAdapter(list).apply { setOnItemClickListener { _, _, position -> list.forEachIndexed { i, item -> item.isClicked = (i == position) } @@ -166,9 +176,13 @@ class FoodRecognizeActivity : BaseActivity() { * 初始化 RecyclerView */ private fun initRecyclerView() { - binding.recyclerView.run { - layoutManager = GridLayoutManager(this@FoodRecognizeActivity, 2) - adapter = this@FoodRecognizeActivity.adapter + binding.recyclerView.let { + it.layoutManager = GridLayoutManager(this@FoodRecognizeActivity, 2) + it.adapter = adapter + it.isVerticalScrollBarEnabled = false + it.removeOnScrollListener(scrollListener) + it.addOnScrollListener(scrollListener) + it.post { updateScrollIndicator() } } updateListVisibility() } @@ -178,12 +192,57 @@ class FoodRecognizeActivity : BaseActivity() { */ private fun updateListVisibility() { if (list.isEmpty()) { - binding.recyclerView.gone() + binding.flListContainer.gone() } else { - binding.recyclerView.visible() + binding.flListContainer.visible() + binding.recyclerView.post { updateScrollIndicator() } } } + /** + * 根据 RecyclerView 滚动状态刷新右侧自定义指示条 + */ + private fun updateScrollIndicator() { + val recyclerView = binding.recyclerView + val track = binding.vScrollIndicatorTrack + val thumb = binding.vScrollIndicatorThumb + + if (!recyclerView.canScrollVertically(1) && !recyclerView.canScrollVertically(-1)) { + track.gone() + thumb.gone() + return + } + + val range = recyclerView.computeVerticalScrollRange() + val extent = recyclerView.computeVerticalScrollExtent() + val offset = recyclerView.computeVerticalScrollOffset() + if (range <= 0 || extent <= 0 || range <= extent) { + track.gone() + thumb.gone() + return + } + + val trackHeight = track.height.takeIf { it > 0 } ?: recyclerView.height + if (trackHeight <= 0) return + + val thumbHeight = ((extent.toFloat() / range) * trackHeight) + .toInt() + .coerceAtLeast(scrollIndicatorMinHeightPx) + .coerceAtMost(trackHeight) + + val maxTop = (trackHeight - thumbHeight).coerceAtLeast(0) + val scrollable = (range - extent).coerceAtLeast(1) + val thumbTop = ((offset.toFloat() / scrollable) * maxTop).toInt().coerceIn(0, maxTop) + + if (thumb.layoutParams.height != thumbHeight) { + thumb.layoutParams = thumb.layoutParams.apply { height = thumbHeight } + } + thumb.translationY = thumbTop.toFloat() + + track.visible() + thumb.visible() + } + /** * 初始化按钮点击事件 */ @@ -219,6 +278,7 @@ class FoodRecognizeActivity : BaseActivity() { adapter.notifyDataSetChanged() binding.tvSelectedFood.text = item.goodsName ?: "-" updateListVisibility() + binding.recyclerView.post { updateScrollIndicator() } } /** diff --git a/app/src/main/java/com/shuwei/dish/match/ui/PrepareCookActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/PrepareCookActivity.kt index c801e10..332c276 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/PrepareCookActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/PrepareCookActivity.kt @@ -122,11 +122,18 @@ class PrepareCookActivity : BaseActivity() { } private fun addViewClickListener() { + binding.tvShowWeight.clickWithDebounce { WeightUtil.tareTwo(AddressUtil.ONE) } WeightUtil.addWeightListener( weightKey = TAG, getWeight = { address, state, weight -> if (address == AddressUtil.ONE && state == WeightUtil.STATE_STABLE) { runOnUiThread { + binding.tvShowWeight.run { + if (tag != weight) { + text = "称重:${weight}g" + tag = weight + } + } recognizeFood(weight) } } @@ -222,13 +229,12 @@ class PrepareCookActivity : BaseActivity() { existing.isSetFinished = true dishPartAdapter.notifyItemChanged(list.indexOf(existing)) } else { - list.add(entity.also { + dishPartAdapter.add(entity.also { it.isNewDishType = true it.isSetFinished = true }) - val position = list.size - 1 - dishPartAdapter.notifyItemInserted(position) - binding.rvDishPartList.smoothScrollToPosition(position) + + binding.rvDishPartList.smoothScrollToPosition(list.size - 1) } } @@ -280,11 +286,14 @@ class PrepareCookActivity : BaseActivity() { netViewModel.foodDetailState.collect { state -> when (state) { is UiState.Success -> { + // 防止 StateFlow 重放导致 list 被重复清空 + if (isDetailLoaded) return@collect val detail = state.data if (detail == null) { toast("查询菜品信息为空") return@collect } + isDetailLoaded = true loadDishDetail(detail) } @@ -336,6 +345,7 @@ class PrepareCookActivity : BaseActivity() { } private var firstReqSize = 0 + private var isDetailLoaded = false private val list = mutableListOf() private val dishPartAdapter by lazy { DishPartAdapter(list = list).apply { @@ -438,8 +448,8 @@ class PrepareCookActivity : BaseActivity() { */ private fun saveDataRemindDialog() { CommonDialog(this) - .setTitle("温馨提示") - .setContent("您好,当前页面存在未保存的数据,确认返回吗?") + .setTitle("返回提示") + .setContent("您好,当前页面存在未保存的数据,\n确认返回吗?") .setNegativeButton("取消") .setPositiveButton("确认") { if (SpTool.cookMode == 1 && pageFrom == HOME) { diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SamplingListActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SamplingListActivity.kt index 621f209..f53e80b 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SamplingListActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SamplingListActivity.kt @@ -369,7 +369,7 @@ class SamplingListActivity : BaseActivity() { private fun showDeviceConfigDialog() { CommonDialog(this) - .setTitle("温馨提示") + .setTitle("配置提示") .setContent("请先在设备配置页面进行调料设置") .setNegativeButton("取消") .setPositiveButton("去设置") { startActivity() } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SelectDishActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SelectDishActivity.kt index f3ac5b6..d67763a 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SelectDishActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SelectDishActivity.kt @@ -84,7 +84,7 @@ class SelectDishActivity : BaseActivity() { private fun showDeviceConfigDialog() { CommonDialog(this) - .setTitle("温馨提示") + .setTitle("配置提示") .setContent("请先在设备配置页面进行调料设置") .setNegativeButton("取消") .setPositiveButton("去设置") { startActivity() } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt index 194e71e..d04501d 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt @@ -115,7 +115,7 @@ class SettingActivity : BaseActivity() { private fun showNotGrantedCameraPermissionDialog() { CommonDialog(this) - .setTitle("温馨提示") + .setTitle("权限提示") .setContent("暂无相机权限,无法使用食材采集功能,请确认是否同意开始权限?") .setNegativeButton("不同意") .setPositiveButton("同意") { 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 75cb2d2..66d2bbc 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 @@ -423,8 +423,8 @@ class SubmitFoodActivity : BaseActivity() { */ private fun remindSaveDataDialog() { CommonDialog(this) - .setTitle("温馨提示") - .setContent("请确认是否存在未保存的数据?") + .setTitle("保存提示") + .setContent("可能存在未保存的数据,请确认?") .setNegativeButton("取消,留在页面") .setNeutralButton("返回上页,不保存") { finish() } .setPositiveButton("保存为烹饪中菜品") { cook() } @@ -436,7 +436,7 @@ class SubmitFoodActivity : BaseActivity() { */ private fun showRemindDialog(content: CharSequence, action: () -> Unit) { CommonDialog(this) - .setTitle("温馨提示") + .setTitle(food?.foodName ?: "温馨提示") .setContent(content) .setNegativeButton("取消") .setPositiveButton("确认") { action() } diff --git a/app/src/main/res/drawable/scrollbar_thumb_food_recognize.xml b/app/src/main/res/drawable/scrollbar_thumb_food_recognize.xml new file mode 100644 index 0000000..cfa685a --- /dev/null +++ b/app/src/main/res/drawable/scrollbar_thumb_food_recognize.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable/scrollbar_track_food_recognize.xml b/app/src/main/res/drawable/scrollbar_track_food_recognize.xml new file mode 100644 index 0000000..ab39449 --- /dev/null +++ b/app/src/main/res/drawable/scrollbar_track_food_recognize.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_food_recognize.xml b/app/src/main/res/layout/activity_food_recognize.xml index 8a70217..4b5f5ac 100644 --- a/app/src/main/res/layout/activity_food_recognize.xml +++ b/app/src/main/res/layout/activity_food_recognize.xml @@ -8,83 +8,115 @@ android:padding="16dp" tools:background="@color/white"> - + + + + tools:src="@mipmap/ic_launcher" /> + + + + - - - + - - + + - - + + - - + + + + + + + + diff --git a/app/src/main/res/layout/activity_prepare_cook.xml b/app/src/main/res/layout/activity_prepare_cook.xml index fa0c546..adf6cf8 100644 --- a/app/src/main/res/layout/activity_prepare_cook.xml +++ b/app/src/main/res/layout/activity_prepare_cook.xml @@ -75,6 +75,16 @@ android:textColor="@color/black666" android:textSize="28sp" /> + +