From 03c5aee7854d24e91650b737785b6f4d4213ad67 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Fri, 24 Apr 2026 15:37:57 +0800 Subject: [PATCH] =?UTF-8?q?refactor(ui):=20=E9=87=8D=E6=9E=84=E4=B8=BB?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E9=A3=9F=E7=89=A9=E5=88=97=E8=A1=A8=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E5=92=8C=E6=94=AF=E4=BB=98=E6=A8=A1=E5=BC=8F=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将原有的RecyclerView替换为FrameLayout容器,实现动态布局加载 - 新增layout_main_food_list.xml和layout_main_food_list2.xml两个布局文件 - 实现联合支付和独立支付两种模式下的不同UI展示 - 集成食物详情显示功能,通过include方式引入layout_eat_detail.xml - 更新数据绑定逻辑,支持两种支付模式下的食物列表显示 - 迁移SharedPreferences操作至SpTool工具类统一管理 - 优化食物识别结果显示逻辑和搜索按钮状态控制 - 重构RecyclerView初始化和适配器设置代码结构 --- .../sw/dualscreen/activity/MainActivity.kt | 84 +++++++++++++------ .../activity/fragment/BusinessFragment.kt | 5 +- .../presentation/MainScreenPresentation.kt | 31 ++++--- .../java/com/sw/dualscreen/utils/SpTool.kt | 9 +- app/src/main/res/layout/activity_main.xml | 41 +-------- app/src/main/res/layout/layout_eat_detail.xml | 2 + .../main/res/layout/layout_main_food_list.xml | 42 ++++++++++ .../res/layout/layout_main_food_list2.xml | 40 +++++++++ 8 files changed, 178 insertions(+), 76 deletions(-) create mode 100644 app/src/main/res/layout/layout_main_food_list.xml create mode 100644 app/src/main/res/layout/layout_main_food_list2.xml diff --git a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt index 67d713b..e97ddb5 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt @@ -13,6 +13,7 @@ import android.text.TextUtils import android.view.Display import android.view.View import android.view.ViewOutlineProvider +import android.widget.TextView import androidx.activity.OnBackPressedCallback import androidx.activity.viewModels import androidx.camera.core.CameraSelector @@ -22,13 +23,18 @@ import androidx.camera.core.ImageCaptureException import androidx.camera.core.Preview import androidx.camera.lifecycle.ProcessCameraProvider import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.google.common.util.concurrent.ListenableFuture import com.sw.dualscreen.GlobalData import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.adapter.MainFoodListAdapter import com.sw.dualscreen.databinding.ActivityMainBinding +import com.sw.dualscreen.databinding.LayoutEatDetailBinding +import com.sw.dualscreen.databinding.LayoutMainFoodList2Binding +import com.sw.dualscreen.databinding.LayoutMainFoodListBinding import com.sw.dualscreen.dialog.EnvSwitchDialog import com.sw.dualscreen.dialog.RemindDialog import com.sw.dualscreen.ext.dp @@ -180,6 +186,10 @@ class MainActivity : BaseActivity() { // SPUtil.getInstance().get(GlobalKey.KEY_SETTLEMENT_MODE, 1) // } + private lateinit var rvFoodList: RecyclerView + private lateinit var tvToSearch: TextView + lateinit var layoutEatDetailBinding: LayoutEatDetailBinding + override fun getViewModel(): BaseViewModel { return viewModel } @@ -202,25 +212,66 @@ class MainActivity : BaseActivity() { initData() } + private fun initLayoutEatDetailBinding(mode: Int) { + binding.flFoodList.removeAllViews() + if (mode == 0) { + //联合支付 + val b = LayoutMainFoodList2Binding.inflate(layoutInflater, binding.flFoodList, true) + rvFoodList = b.rvFoodList + tvToSearch = b.tvToSearch + layoutEatDetailBinding = b.detailInclude + layoutEatDetailBinding.llFoodTitle.gone() +// layoutEatDetailBinding.root.invisible() + } else { + //独立支付 + val b = LayoutMainFoodListBinding.inflate(layoutInflater, binding.flFoodList, true) + rvFoodList = b.rvFoodList + tvToSearch = b.tvToSearch + layoutEatDetailBinding = b.detailInclude + layoutEatDetailBinding.llFoodTitle.gone() + layoutEatDetailBinding.root.gone() + } + tvToSearch.setOnClickListener { + bottomSheetDialog = CustomBottomSheetDialog.newInstance(viewModel) { + checkedItem = it + it.photoUri = null + adapter.items.forEachIndexed { index, info -> + adapter.items[index].isChecked = false + } + adapter.notifyDataSetChanged() + resetSelectedFood(it) + } + bottomSheetDialog!!.show(supportFragmentManager, "CustomBottomSheetDialog") + } + + rvFoodList.let { + it.layoutManager = GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false) + it.adapter = adapter + } + } + private fun initData() { startFaceTask() } private fun initView() { + initLayoutEatDetailBinding(SpTool.settlementMode) viewModel.getDeviceConfig { deviceConfig -> runOnUiThread { if (deviceConfig == null) { ToastUtils.showToast("获取设备配置数据失败") + initLayoutEatDetailBinding(SpTool.settlementMode) return@runOnUiThread } //结算模式:1-独立支付,2-联合结算 settlementMode = if (deviceConfig.payType == 2) 0 else 1 - SPUtil.getInstance().put(GlobalKey.KEY_SETTLEMENT_MODE, settlementMode) + SpTool.settlementMode = settlementMode GlobalData.appId = deviceConfig.arcsoftAppId ?: "" GlobalData.sdkKey = deviceConfig.arcsoftSdkKey ?: "" GlobalData.activeKey = deviceConfig.arcsoftActiveKey ?: "" viewModel.activeEngine() + initLayoutEatDetailBinding(settlementMode) } } updateDateTime() @@ -264,23 +315,6 @@ class MainActivity : BaseActivity() { } } binding.previewView.clipToOutline = true - binding.tvToSearch.setOnClickListener { - bottomSheetDialog = CustomBottomSheetDialog.newInstance(viewModel) { - checkedItem = it - it.photoUri = null - adapter.items.forEachIndexed { index, info -> - adapter.items[index].isChecked = false - } - adapter.notifyDataSetChanged() - resetSelectedFood(it) - } - bottomSheetDialog!!.show(supportFragmentManager, "CustomBottomSheetDialog") - } - - binding.recyclerview.let { - it.layoutManager = GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false) - it.adapter = adapter - } binding.tvFoodName.setOnClickListener { SensorScaleUtils.zero() } @@ -545,7 +579,7 @@ class MainActivity : BaseActivity() { log("registerDataChange识别后查询接口数据:$queryData,识别数据:$recData") if (list.isEmpty()) { foodRecognizeState = false - binding.tvToSearch.let { + tvToSearch.let { it.text = "未查询到,手动搜索" it.visible() } @@ -571,7 +605,7 @@ class MainActivity : BaseActivity() { // } adapter.submitList(list) - binding.recyclerview.visible() + rvFoodList.visible() checkedItem = list[0].also { it.photoUri = lastPhotoUri @@ -582,10 +616,11 @@ class MainActivity : BaseActivity() { // lastPhotoUri = null LightManager.closeRedLight() - binding.tvToSearch.let { + tvToSearch.let { it.text = "以上都不是,手动搜索" it.visible() } + log("registerDataChange识别完成:visible=${rvFoodList.isVisible},count=${rvFoodList.childCount}") } private fun setupCamera() { @@ -756,9 +791,10 @@ class MainActivity : BaseActivity() { @SuppressLint("NotifyDataSetChanged") fun clearRecognizeFood() { log("clearRecognizeFood") - binding.recyclerview.invisible() + rvFoodList.invisible() + layoutEatDetailBinding.root.invisible() adapter.submitList(null) - binding.tvToSearch.gone() + tvToSearch.gone() binding.previewView.visible() binding.ivImg.gone() @@ -1294,7 +1330,7 @@ class MainActivity : BaseActivity() { //binding.layoutRescan.visibility = View.VISIBLE withContext(Dispatchers.Main) { - binding.tvToSearch.let { + tvToSearch.let { it.text = "未识别到,手动搜索" it.visible() } diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/BusinessFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/BusinessFragment.kt index 4e93aef..aeaaafb 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/fragment/BusinessFragment.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/BusinessFragment.kt @@ -9,6 +9,7 @@ import com.sw.dualscreen.model.response.ChargeModeEvent import com.sw.dualscreen.model.response.ResetRecognizeEvent import com.sw.dualscreen.sdk.SensorScaleUtils import com.sw.dualscreen.utils.SPUtil +import com.sw.dualscreen.utils.SpTool import com.sw.plate.utils.ToastUtils import org.greenrobot.eventbus.EventBus import kotlin.math.roundToInt @@ -23,8 +24,8 @@ class BusinessFragment: BaseFragment() { binding.rgSettlement.let { //val settlementMode = if (binding.rgSettlement.checkedRadioButtonId == R.id.rbJointPayment) 0 else 1 - val mode = SPUtil.getInstance().get(GlobalKey.KEY_SETTLEMENT_MODE, 1) - it.check(if (mode == 0) R.id.rbJointPayment else R.id.rbIndependentPayment) + //val mode = SPUtil.getInstance().get(GlobalKey.KEY_SETTLEMENT_MODE, 1) + it.check(if (SpTool.settlementMode == 0) R.id.rbJointPayment else R.id.rbIndependentPayment) binding.rbJointPayment.isEnabled = false binding.rbIndependentPayment.isEnabled = false } diff --git a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt index 3a3ad90..b0c7cf6 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt @@ -16,11 +16,11 @@ import android.view.ViewTreeObserver import android.widget.FrameLayout import androidx.core.content.ContextCompat import androidx.core.view.isVisible -import androidx.core.view.postDelayed import androidx.core.view.updateLayoutParams import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.arcsoft.face.ErrorInfo import com.sw.dualscreen.BuildConfig import com.sw.dualscreen.GlobalKey @@ -64,7 +64,6 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.drop import kotlinx.coroutines.launch import timber.log.Timber -import java.text.DecimalFormat import kotlin.math.abs import kotlin.math.max import kotlin.math.roundToInt @@ -327,6 +326,7 @@ class MainScreenPresentation( loadOrderList(userId) { loadUserNutritionData(userId) } + activity.layoutEatDetailBinding.root.visible() } else { //独立支付 loadUserNutritionData(userId) @@ -776,10 +776,14 @@ class MainScreenPresentation( val fruitsVegetables = energy.fruitsVegetables val meatEggs = energy.meatEggs - binding.detailInclude.tvTotalCalorie.text = "总热量:${totalKcal.roundedDecimalPlace(1)}千卡" + val showTotalCalorie = "总热量:${totalKcal.roundedDecimalPlace(1)}千卡" + binding.detailInclude.tvTotalCalorie.text = showTotalCalorie + activity.layoutEatDetailBinding.tvTotalCalorie.text = showTotalCalorie val totalWeight = (userNutrition?.eatWeightSum ?: 0.0) + weight - binding.detailInclude.tvTotalWeight.text = "总重量:${totalWeight.roundedDecimalPlace(1)}克" + val showTotalWeight = "总重量:${totalWeight.roundedDecimalPlace(1)}克" + binding.detailInclude.tvTotalWeight.text = showTotalWeight + activity.layoutEatDetailBinding.tvTotalWeight.text = showTotalWeight val include = binding.nutritionInclude @@ -1449,6 +1453,16 @@ class MainScreenPresentation( FoodOrderAdapter(foodOrderList) } + private fun initRv(rv: RecyclerView) { + rv.run { + if (adapter == null) { + layoutManager = + LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false) + adapter = foodOrderAdapter + } + } + } + /** * 加载订单列表 */ @@ -1460,13 +1474,8 @@ class MainScreenPresentation( it.root.updateLayoutParams { height = activity.screenSize[1] / 2 + 120.dp } - it.rvFoodList.run { - if (adapter == null) { - layoutManager = - LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false) - adapter = foodOrderAdapter - } - } + initRv(it.rvFoodList) + initRv(activity.layoutEatDetailBinding.rvFoodList) userViewModel.getFoodOrderList(userId) { model -> activity.runOnUiThread { if (model == null) return@runOnUiThread diff --git a/app/src/main/java/com/sw/dualscreen/utils/SpTool.kt b/app/src/main/java/com/sw/dualscreen/utils/SpTool.kt index ec7edff..53a18bd 100644 --- a/app/src/main/java/com/sw/dualscreen/utils/SpTool.kt +++ b/app/src/main/java/com/sw/dualscreen/utils/SpTool.kt @@ -17,13 +17,13 @@ object SpTool { var lastFaceTimestamp: Long - get() = spUtil?.get(LAST_FACE_TIMESTAMP, 0L)?:0L + get() = spUtil?.get(LAST_FACE_TIMESTAMP, 0L) ?: 0L set(timestamp) { spUtil?.put(LAST_FACE_TIMESTAMP, timestamp) } var firstGetFace: Boolean - get() = spUtil?.get(IS_FIRST_GET_FACE, true)?:true + get() = spUtil?.get(IS_FIRST_GET_FACE, true) ?: true set(value) { spUtil?.boolean(IS_FIRST_GET_FACE, value) } @@ -33,5 +33,10 @@ object SpTool { set(value) { spUtil?.put(GlobalKey.KEY_BASE_URL, value) } + var settlementMode: Int + get() = spUtil?.get(GlobalKey.KEY_SETTLEMENT_MODE, 0) ?: 0 + set(value) { + spUtil?.put(GlobalKey.KEY_SETTLEMENT_MODE, value) + } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2f703a2..3d6111a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -92,51 +92,18 @@ - - - - - - - - + android:layout_weight="1"/> @@ -54,6 +55,7 @@ android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" + android:overScrollMode="never" tools:listitem="@layout/layout_food_list_header" /> + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_main_food_list2.xml b/app/src/main/res/layout/layout_main_food_list2.xml new file mode 100644 index 0000000..af030ef --- /dev/null +++ b/app/src/main/res/layout/layout_main_food_list2.xml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file