From c6badf2ca7247f2e02f7ccf8da8c15b28798ba53 Mon Sep 17 00:00:00 2001 From: zxj <275873859@qq.com> Date: Mon, 4 Aug 2025 18:02:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86=E7=83=AD=E9=87=8F?= =?UTF-8?q?=E5=80=BC=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sw/dualscreen/activity/MainActivity.kt | 16 +-- .../java/com/sw/dualscreen/ext/CommonExt.kt | 2 + .../model/response/DinnerTypeInfo.kt | 42 +++++++ .../sw/dualscreen/model/response/FoodInfo.kt | 24 +++- ...{NutritionData.kt => UserNutritionData.kt} | 108 +++++++++++++++++- .../sw/dualscreen/network/api/ApiService.kt | 15 ++- .../SecondaryScreenPresentation.kt | 100 ++++++++++++++-- .../presentation/UserNutritionUtils.kt | 79 +++++++++++++ .../dualscreen/repository/RemoteRepository.kt | 13 ++- .../com/sw/dualscreen/sdk/SensorScaleUtils.kt | 1 + .../sw/dualscreen/view/CustomImageView.java | 35 +++++- .../sw/dualscreen/viewmodel/UserViewModel.kt | 24 +++- .../main/res/layout/item_user_nutrition.xml | 2 +- app/src/main/res/values/themes.xml | 2 +- 14 files changed, 431 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/com/sw/dualscreen/model/response/DinnerTypeInfo.kt rename app/src/main/java/com/sw/dualscreen/model/response/{NutritionData.kt => UserNutritionData.kt} (54%) create mode 100644 app/src/main/java/com/sw/dualscreen/presentation/UserNutritionUtils.kt 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 670d422..5ccef49 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt @@ -54,6 +54,7 @@ class MainActivity : AppCompatActivity() { private var checkedItem: FoodInfo? = null private var imageAnalysis: ImageAnalysis? = null private var cameraProviderFuture: ListenableFuture? = null + private var canIdentify: Boolean = true override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -156,14 +157,15 @@ class MainActivity : AppCompatActivity() { } } viewModel.getIdentifiedFoodList() -// SensorScaleUtils.startScale { weight -> + SensorScaleUtils.startScale { weight -> // Timber.d("weight = $weight") -// if (weight > 0.0) { -// if (canIndentify) { -// viewModel.getIdentifiedFoodList() -// } -// } -// } + if (weight > 0.0) { + if (canIdentify) { + canIdentify = false + viewModel.getIdentifiedFoodList() + } + } + } } private fun createAdapter(): GenericItemAdapter { diff --git a/app/src/main/java/com/sw/dualscreen/ext/CommonExt.kt b/app/src/main/java/com/sw/dualscreen/ext/CommonExt.kt index 2bd27a8..d04562c 100644 --- a/app/src/main/java/com/sw/dualscreen/ext/CommonExt.kt +++ b/app/src/main/java/com/sw/dualscreen/ext/CommonExt.kt @@ -55,6 +55,8 @@ val Float.sp: Float Resources.getSystem().displayMetrics ) +fun Double.format2String(): String = "%.1f".format(this) + // 添加扩展函数 fun ImageProxy.toSafeBitmap(): Bitmap { val yBuffer = planes[0].buffer // Y diff --git a/app/src/main/java/com/sw/dualscreen/model/response/DinnerTypeInfo.kt b/app/src/main/java/com/sw/dualscreen/model/response/DinnerTypeInfo.kt new file mode 100644 index 0000000..152378b --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/model/response/DinnerTypeInfo.kt @@ -0,0 +1,42 @@ +package com.sw.dualscreen.model.response + + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import kotlinx.parcelize.Parcelize + +@Parcelize +data class DinnerTypeInfo( + @SerializedName("dinnerType") + val dinnerType: DinnerType? = DinnerType() +) : Parcelable { + @Parcelize + data class DinnerType( + @SerializedName("createBy") + val createBy: String? = "", + @SerializedName("createTime") + val createTime: String? = "", + @SerializedName("delFlag") + val delFlag: Int? = 0, + @SerializedName("dinnerType") + val dinnerType: String? = "", + @SerializedName("endTime") + val endTime: String? = "", + @SerializedName("id") + val id: Int? = 0, + @SerializedName("isSync") + val isSync: Int? = 0, + @SerializedName("isSyncCopy") + val isSyncCopy: Int? = 0, + @SerializedName("restId") + val restId: String? = "", + @SerializedName("startTime") + val startTime: String? = "", + @SerializedName("sysOrgCode") + val sysOrgCode: String? = "", + @SerializedName("updateBy") + val updateBy: String? = "", + @SerializedName("updateTime") + val updateTime: String? = "" + ) : Parcelable +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/model/response/FoodInfo.kt b/app/src/main/java/com/sw/dualscreen/model/response/FoodInfo.kt index 1bd6863..d7900bd 100644 --- a/app/src/main/java/com/sw/dualscreen/model/response/FoodInfo.kt +++ b/app/src/main/java/com/sw/dualscreen/model/response/FoodInfo.kt @@ -2,6 +2,7 @@ package com.sw.dualscreen.model.response import android.os.Parcelable +import android.text.TextUtils import com.google.gson.annotations.SerializedName import kotlinx.parcelize.Parcelize @@ -206,7 +207,28 @@ data class FoodInfo( val vegetable: String? = "", @SerializedName("vegetableRecommend") val vegetableRecommend: String? = "" - ) : Parcelable + ) : Parcelable { + + fun fruitsValue(): Double = + if (TextUtils.isEmpty(fruits)) + 0.0 + else fruits!!.toDouble() + + fun grainValue(): Double = + if (TextUtils.isEmpty(grain)) + 0.0 + else grain!!.toDouble() + + fun vegetableValue(): Double = + if (TextUtils.isEmpty(vegetable)) + 0.0 + else vegetable!!.toDouble() + + fun meatValue(): Double = + if (TextUtils.isEmpty(meat)) + 0.0 + else meat!!.toDouble() + } @Parcelize data class StFoodInfoSetting( diff --git a/app/src/main/java/com/sw/dualscreen/model/response/NutritionData.kt b/app/src/main/java/com/sw/dualscreen/model/response/UserNutritionData.kt similarity index 54% rename from app/src/main/java/com/sw/dualscreen/model/response/NutritionData.kt rename to app/src/main/java/com/sw/dualscreen/model/response/UserNutritionData.kt index 935577f..838333f 100644 --- a/app/src/main/java/com/sw/dualscreen/model/response/NutritionData.kt +++ b/app/src/main/java/com/sw/dualscreen/model/response/UserNutritionData.kt @@ -2,6 +2,7 @@ package com.sw.dualscreen.model.response import android.os.Parcelable +import android.text.TextUtils import com.google.gson.annotations.SerializedName import kotlinx.parcelize.Parcelize @@ -9,69 +10,172 @@ import kotlinx.parcelize.Parcelize * 就餐数据 */ @Parcelize -data class NutritionData( +data class UserNutritionData( + /** + * 总胆固醇 + */ @SerializedName("cho") val cho: String? = "", + /** + * 饮食纤维 + */ @SerializedName("dietFiber") val dietFiber: String? = "", + /** + * 能量 + */ @SerializedName("energy") val energy: String? = "", + /** + * 脂肪 + */ @SerializedName("fat") val fat: String? = "", + /** + * 食物类型和实际摄入量清单 + */ @SerializedName("foodTypeAndRealIntakeVoList") val foodTypeAndRealIntakeVoList: List? = listOf(), @SerializedName("foodWeight") val foodWeight: String? = "", @SerializedName("message") val message: String? = "", + /** + * 钠 + */ @SerializedName("na") val na: String? = "", + /** + * 蛋白质 + */ @SerializedName("protein") val protein: String? = "", + /** + * 最大推荐热量 + */ @SerializedName("recommendMax") val recommendMax: String? = "", + /** + * 最小推荐热量 + */ @SerializedName("recommendMin") val recommendMin: String? = "", + /** + * 热量详情 + */ @SerializedName("stFoodInfoPagoda") val stFoodInfoPagoda: StFoodInfoPagoda? = StFoodInfoPagoda(), @SerializedName("stUserFoodInfoList") val stUserFoodInfoList: List? = listOf(), + /** + * 每日总热量 + */ @SerializedName("totalEnergyCalculateScore") val totalEnergyCalculateScore: String? = "", + /** + * 用户所在部门 + */ @SerializedName("userDept") val userDept: String? = "", + /** + * 用户id + */ @SerializedName("userId") val userId: String? = "", + /** + * 姓名 + */ @SerializedName("userName") val userName: String? = "" ) : Parcelable { + fun recommendMaxValue(): Double = + if (TextUtils.isEmpty(recommendMax)) 0.0 + else recommendMax!!.toDouble() + + fun recommendMinValue(): Double = + if (TextUtils.isEmpty(recommendMin)) 0.0 + else recommendMin!!.toDouble() + + fun energyValue(): Double = + if (TextUtils.isEmpty(energy)) 0.0 + else energy!!.toDouble() + + fun totalEnergyCalculateScoreValue(): Double = + if (TextUtils.isEmpty(totalEnergyCalculateScore)) 0.0 + else totalEnergyCalculateScore!!.toDouble() + @Parcelize data class StFoodInfoPagoda( + /** + * 水果 + */ @SerializedName("fruits") val fruits: String? = "", @SerializedName("fruitsRecommend") val fruitsRecommend: String? = "", + /** + * 粮食 + */ @SerializedName("grain") val grain: String? = "", @SerializedName("grainRecommend") val grainRecommend: String? = "", + /** + * 肉 + */ @SerializedName("meat") val meat: String? = "", @SerializedName("meatRecommend") val meatRecommend: String? = "", + /** + * 油 + */ @SerializedName("oil") val oil: String? = "", + /** + * 盐 + */ @SerializedName("salt") val salt: String? = "", + /** + * 大豆 + */ @SerializedName("soya") val soya: String? = "", @SerializedName("soyaRecommend") val soyaRecommend: String? = "", + /** + * 糖 + */ @SerializedName("sugar") val sugar: String? = "", + /** + * 蔬菜 + */ @SerializedName("vegetable") val vegetable: String? = "", @SerializedName("vegetableRecommend") val vegetableRecommend: String? = "" - ) : Parcelable + ) : Parcelable { + fun fruitsValue(): Double = + if (TextUtils.isEmpty(fruits)) + 0.0 + else fruits!!.toDouble() + + fun grainValue(): Double = + if (TextUtils.isEmpty(grain)) + 0.0 + else grain!!.toDouble() + + fun vegetableValue(): Double = + if (TextUtils.isEmpty(vegetable)) + 0.0 + else vegetable!!.toDouble() + + fun meatValue(): Double = + if (TextUtils.isEmpty(meat)) + 0.0 + else meat!!.toDouble() + + } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/network/api/ApiService.kt b/app/src/main/java/com/sw/dualscreen/network/api/ApiService.kt index 83e4c3b..8837c56 100644 --- a/app/src/main/java/com/sw/dualscreen/network/api/ApiService.kt +++ b/app/src/main/java/com/sw/dualscreen/network/api/ApiService.kt @@ -3,10 +3,11 @@ package com.sw.dualscreen.network.api import com.sw.dualscreen.GlobalData import com.sw.dualscreen.model.request.UserNutritionParam import com.sw.dualscreen.model.response.ApiResponse +import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.EquipmentInfo import com.sw.dualscreen.model.response.FoodInfo -import com.sw.dualscreen.model.response.NutritionData import com.sw.dualscreen.model.response.UserFaceInfo +import com.sw.dualscreen.model.response.UserNutritionData import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.Header @@ -78,7 +79,17 @@ interface ApiService { @Query("restId") restId: String, @Query("userId") userId: String, @Query("foodId") foodId: String, - ): ApiResponse + ): ApiResponse + + /** + * 获取当前餐点类型 + */ + @GET + suspend fun getDinnerType( + @Url url: String = "${GlobalData.appBaseUrl}/zhstapi/zhst/getCanteenDinnerType", + @Query("appVersion") appVersion: String = GlobalData.appVersion, + @Query("canteenId") restId: String, + ): ApiResponse /** * 提交就餐数据 diff --git a/app/src/main/java/com/sw/dualscreen/presentation/SecondaryScreenPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/SecondaryScreenPresentation.kt index f9e80d7..895f703 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/SecondaryScreenPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/SecondaryScreenPresentation.kt @@ -30,8 +30,13 @@ import com.sw.dualscreen.activity.MainActivity import com.sw.dualscreen.databinding.ItemUserNutritionBinding import com.sw.dualscreen.databinding.PresentationSecondaryScreenBinding import com.sw.dualscreen.ext.dp +import com.sw.dualscreen.ext.format2String import com.sw.dualscreen.ext.maskName +import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.FoodInfo +import com.sw.dualscreen.model.response.UserNutritionData +import com.sw.dualscreen.sdk.SensorScaleUtils +import com.sw.dualscreen.utils.Debouncer import com.sw.dualscreen.utils.GlideUtils import com.sw.dualscreen.viewmodel.UserViewModel import com.sw.plate.utils.ToastUtils @@ -70,6 +75,8 @@ class SecondaryScreenPresentation( // 当前食物信息 private var currentFood: FoodInfo? = null + private var userNutritionData: UserNutritionData? = null + private var dinnerType: DinnerTypeInfo? = null private lateinit var itemUserNutritionBinding: ItemUserNutritionBinding private lateinit var stepChangeCallback: (Int) -> Unit @@ -92,14 +99,16 @@ class SecondaryScreenPresentation( viewModel.nutritionData.collect { Timber.d("registerDataChange nutritionData = $it") if (it == null) return@collect + userNutritionData = it + step3() itemUserNutritionBinding.tvUserName.text = it.userName.maskName() itemUserNutritionBinding.tvRecommendHeat.text = "推荐热量:${it.recommendMin}-${it.recommendMax}" - - itemUserNutritionBinding.customKcalColumn.setCustomHeight(280, true) - itemUserNutritionBinding.customFoodColumn.setCustomHeightPercent(1f, true) - itemUserNutritionBinding.customVegetableColumn.setCustomHeightPercent(0.5f, true) - itemUserNutritionBinding.customMeatColumn.setCustomHeightPercent(0f, true) + } + } + activity.lifecycleScope.launch { + viewModel.dinnerTypeInfo.collect { + dinnerType = it } } } @@ -163,6 +172,8 @@ class SecondaryScreenPresentation( binding.tvBottomTip.visibility = View.VISIBLE itemUserNutritionBinding.clNutritionData.visibility = View.GONE + stopSensorScale() + viewModel.getDinnerType() } /** @@ -211,6 +222,7 @@ class SecondaryScreenPresentation( } binding.tvFoodInfo.text = currentFood!!.foodName + startSensorScale() GlideUtils.loadRoundCornerImage( context, @@ -229,11 +241,82 @@ class SecondaryScreenPresentation( itemUserNutritionBinding.clNutritionData.visibility = View.VISIBLE viewModel.getUserNutritionData( - userId = "187c96f7bf294c08bc1d1e57b90a7210", + userId = userNutritionData!!.userId!!, foodId = currentFood!!.id!! ) } + private fun startSensorScale() { + var lastWeight = 0.0 + val debouncer = Debouncer(1000) + SensorScaleUtils.startScale { weight -> + if (weight == lastWeight) return@startScale + Timber.d("registerDataChange weight = $weight") + lastWeight = weight + if (currentFood == null) return@startScale + if (userNutritionData == null) return@startScale + if (dinnerType == null) return@startScale + debouncer.debounce { + val calcResultInfo = UserNutritionUtils.calculateNutrition( + currentFood!!, + userNutritionData!!, + weight, + dinnerType = dinnerType!!.dinnerType!!.dinnerType!! + ) + Timber.d("calcResultInfo = $calcResultInfo") + activity.runOnUiThread { + val totalKcal = calcResultInfo.totalKcal + val grain = calcResultInfo.grain + val fruits = calcResultInfo.fruits + val meat = calcResultInfo.meat + itemUserNutritionBinding.customKcalColumn.setImageDrawable( + true, + totalKcal.first < totalKcal.second + ) + itemUserNutritionBinding.totalKcalTv.text = totalKcal.second.format2String() + itemUserNutritionBinding.customKcalColumn.setCustomHeightPercent( + (totalKcal.second / 100).toFloat(), + true + ) + + itemUserNutritionBinding.customFoodColumn.setImageDrawable( + false, + grain.first < grain.second + ) + itemUserNutritionBinding.totalFoodTv.text = grain.second.format2String() + itemUserNutritionBinding.customFoodColumn.setCustomHeightPercent( + (grain.second / 100).toFloat(), + true + ) + + itemUserNutritionBinding.customVegetableColumn.setImageDrawable( + false, + fruits.first < fruits.second + ) + itemUserNutritionBinding.totalVegetableTv.text = fruits.second.format2String() + itemUserNutritionBinding.customVegetableColumn.setCustomHeightPercent( + (fruits.second / 100).toFloat(), + true + ) + + itemUserNutritionBinding.customMeatColumn.setImageDrawable( + false, + meat.first < meat.second + ) + itemUserNutritionBinding.totalMeatTv.text = meat.second.format2String() + itemUserNutritionBinding.customMeatColumn.setCustomHeightPercent( + (meat.second / 100).toFloat(), + true + ) + } + } + } + } + + private fun stopSensorScale() { + SensorScaleUtils.closeScale() + } + private fun openCamera(cameraId: String) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED @@ -328,7 +411,8 @@ class SecondaryScreenPresentation( recognizeViewModel.recognizeUserId.observe(activity, Observer { userId: String? -> Timber.i("recognizeUserId observe userId = $userId") -// viewModel.getUserInfoById(memberId = userId?.toInt() ?: 0) + if (userId == null) return@Observer + viewModel.getUserNutritionData(userId = userId, foodId = currentFood!!.id!!) }) recognizeViewModel.drawRectInfoText.observe(activity, Observer { info -> @@ -534,7 +618,7 @@ class SecondaryScreenPresentation( rgbCameraHelper!!.release() rgbCameraHelper = null } - + SensorScaleUtils.closeScale() recognizeViewModel.destroy() super.onStop() } diff --git a/app/src/main/java/com/sw/dualscreen/presentation/UserNutritionUtils.kt b/app/src/main/java/com/sw/dualscreen/presentation/UserNutritionUtils.kt new file mode 100644 index 0000000..577fcc0 --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/presentation/UserNutritionUtils.kt @@ -0,0 +1,79 @@ +package com.sw.dualscreen.presentation + + +import android.text.TextUtils +import com.sw.dualscreen.model.response.FoodInfo +import com.sw.dualscreen.model.response.UserNutritionData + +object UserNutritionUtils { + + /** + * 计算热量信息 + */ + fun calculateNutrition( + foodInfo: FoodInfo, + userModel: UserNutritionData, + weight: Double, + dinnerType: String + ): CalcResultInfo { + // 1. 初始化变量 + var foodKcal = 0.0 + var totalKcal = 0.0 + var (vegetable, meat, fruits, grain) = List(4) { 0.0 } + + // 2. 处理食物信息 + foodKcal = calculateValue(foodInfo.stFoodInfoMaterial?.energyKcal, weight) + + grain = calculateValue(foodInfo.stFoodInfoPagodaAPPVO?.grainValue(), weight) + fruits = calculateValue(foodInfo.stFoodInfoPagodaAPPVO?.fruitsValue(), weight) + vegetable = calculateValue(foodInfo.stFoodInfoPagodaAPPVO?.vegetableValue(), weight) + meat = calculateValue(foodInfo.stFoodInfoPagodaAPPVO?.meatValue(), weight) + + // 3. 合并用户数据 + grain += userModel.stFoodInfoPagoda?.grainValue() ?: 0.0 + fruits += userModel.stFoodInfoPagoda?.fruitsValue() ?: 0.0 + vegetable = vegetable.plus(userModel.stFoodInfoPagoda?.vegetableValue() ?: 0.0) + meat += userModel.stFoodInfoPagoda?.meatValue() ?: 0.0 + + totalKcal = foodKcal + userModel.energyValue() + val fruitsAndVeg = fruits + vegetable + + // 4. 判断当餐最大热量 + val maxKcal = + userModel.totalEnergyCalculateScoreValue() * calculateDinnerTypeRatio(dinnerType) / 10 + + val pagoda = userModel.stFoodInfoPagoda + val calcResult = CalcResultInfo( + totalKcal = maxKcal to totalKcal, + grain = parseMax(pagoda?.grainRecommend) to grain, + fruits = parseMax(pagoda?.fruitsRecommend) + parseMax(pagoda?.vegetableRecommend) to fruitsAndVeg, + meat = parseMax(pagoda?.meatRecommend) to meat + ) + return calcResult + } + + fun parseMax(recommend: String?): Double { + if (TextUtils.isEmpty(recommend) || !recommend!!.contains("-")) return 0.0 + val (min, max) = recommend.split("-") + return max.toDouble() + } + + private fun calculateDinnerTypeRatio(dinnerType: String): Int { + return when (dinnerType) { + "早餐", "晚餐" -> 3 + "午餐" -> 4 + else -> 0 + } + } + + private fun calculateValue(nutrient: Double?, weight: Double): Double { + return weight * (nutrient ?: 1.0) + } + + data class CalcResultInfo( + var totalKcal: Pair, + var grain: Pair, + var fruits: Pair, + var meat: Pair, + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/repository/RemoteRepository.kt b/app/src/main/java/com/sw/dualscreen/repository/RemoteRepository.kt index 3daba10..fcc6b61 100644 --- a/app/src/main/java/com/sw/dualscreen/repository/RemoteRepository.kt +++ b/app/src/main/java/com/sw/dualscreen/repository/RemoteRepository.kt @@ -3,10 +3,11 @@ package com.sw.dualscreen.repository import com.sw.dualscreen.GlobalData import com.sw.dualscreen.model.request.UserNutritionParam import com.sw.dualscreen.model.response.ApiResponse +import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.EquipmentInfo import com.sw.dualscreen.model.response.FoodInfo -import com.sw.dualscreen.model.response.NutritionData import com.sw.dualscreen.model.response.UserFaceInfo +import com.sw.dualscreen.model.response.UserNutritionData import com.sw.dualscreen.network.api.ApiService /** @@ -80,12 +81,20 @@ class RemoteRepository constructor( restId: String = GlobalData.restId, userId: String, foodId: String, - ): ApiResponse { + ): ApiResponse { return safeApiCall { apiService.getUserNutritionData(restId = restId, userId = userId, foodId = foodId) } } + suspend fun getDinnerType( + restId: String = GlobalData.restId, + ): ApiResponse { + return safeApiCall { + apiService.getDinnerType(restId = restId) + } + } + /** * 提交就餐数据 */ diff --git a/app/src/main/java/com/sw/dualscreen/sdk/SensorScaleUtils.kt b/app/src/main/java/com/sw/dualscreen/sdk/SensorScaleUtils.kt index dea005e..85e20c5 100644 --- a/app/src/main/java/com/sw/dualscreen/sdk/SensorScaleUtils.kt +++ b/app/src/main/java/com/sw/dualscreen/sdk/SensorScaleUtils.kt @@ -143,6 +143,7 @@ object SensorScaleUtils { * 关闭称重 */ fun closeScale() { + Log.d(TAG, "closeScale") isOpened = false mSensorScale?.closeScale() mSensorScale == null diff --git a/app/src/main/java/com/sw/dualscreen/view/CustomImageView.java b/app/src/main/java/com/sw/dualscreen/view/CustomImageView.java index 6fc0ab2..66ba235 100644 --- a/app/src/main/java/com/sw/dualscreen/view/CustomImageView.java +++ b/app/src/main/java/com/sw/dualscreen/view/CustomImageView.java @@ -1,15 +1,18 @@ package com.sw.dualscreen.view; import android.animation.ValueAnimator; +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.ViewGroup; import android.view.animation.AlphaAnimation; +import com.sw.dualscreen.R; import com.sw.plate.utils.AppUtil; public class CustomImageView extends androidx.appcompat.widget.AppCompatImageView { @@ -23,29 +26,37 @@ public class CustomImageView extends androidx.appcompat.widget.AppCompatImageVie private static final int MAX_HEIGHT = 280; private boolean isDrawText = false; + private Drawable bigRedDrawable; + private Drawable bigGreenDrawable; + private Drawable redDrawable; + private Drawable greenDrawable; public CustomImageView(Context context) { super(context); - init(); + init(context); } public CustomImageView(Context context, AttributeSet attrs) { super(context, attrs); - init(); + init(context); } public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - init(); + init(context); } - private void init() { + @SuppressLint("UseCompatLoadingForDrawables") + private void init(Context context) { textToDraw = "超标"; mPaint = new Paint();//Paint.ANTI_ALIAS_FLAG mPaint.setColor(Color.WHITE); // Set your desired color mPaint.setTextSize(mTextSize); // Set your desired text size mPaint.setAntiAlias(true); - + bigRedDrawable = context.getDrawable(R.drawable.img_big_red_column); + bigGreenDrawable = context.getDrawable(R.drawable.img_big_green_column); + redDrawable = context.getDrawable(R.drawable.img_red_column); + greenDrawable = context.getDrawable(R.drawable.img_green_column); // Typeface typeface = getResources().getFont(R.font.dakai); // Typeface typeface = Typeface.create(Typeface.createFromAsset(getContext().getAssets(), "fonts/dakai.TTF"), // Typeface.BOLD); // 创建Typeface @@ -69,6 +80,20 @@ public class CustomImageView extends androidx.appcompat.widget.AppCompatImageVie } } + /** + * 设置图片 + * + * @param isBig 大图 + * @param isMore 是否超过 + */ + public void setImageDrawable(boolean isBig, boolean isMore) { + if (isBig) { + setImageDrawable(isMore ? bigRedDrawable : bigGreenDrawable); + } else { + setImageDrawable(isMore ? redDrawable : greenDrawable); + } + } + public void setCustomHeightPercent(float percent, boolean isAnimation) { setCustomHeight((int) (percent * MAX_HEIGHT), isAnimation); } diff --git a/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt b/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt index ee0f61f..784145f 100644 --- a/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt +++ b/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt @@ -5,9 +5,10 @@ import com.arcsoft.face.ErrorInfo import com.sw.dualscreen.GlobalData import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.model.request.UserNutritionParam +import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.FoodInfo -import com.sw.dualscreen.model.response.NutritionData import com.sw.dualscreen.model.response.UserFaceModel +import com.sw.dualscreen.model.response.UserNutritionData import com.sw.inbound.utils.SPUtil import com.sw.plate.App import com.sw.plate.utils.Base64 @@ -35,8 +36,15 @@ class UserViewModel : BaseViewModel() { val searchFoodInfoList: StateFlow> = _searchFoodInfoList // 就餐数据 - private val _nutritionData = MutableStateFlow(null) - val nutritionData: StateFlow = _nutritionData + private val _nutritionData = MutableStateFlow(null) + val nutritionData: StateFlow = _nutritionData + + /** + * 饭点类型 + */ + private val _dinnerTypeInfo = MutableStateFlow(null) + val dinnerTypeInfo: StateFlow = _dinnerTypeInfo + /** * 获取token @@ -179,6 +187,16 @@ class UserViewModel : BaseViewModel() { } } + fun getDinnerType() { + Timber.d("getDinnerType") + launchWithLoading { + val response = repository.getDinnerType() + if (parseResponse(response)) { + _dinnerTypeInfo.value = response.result + } + } + } + /** * 提交就餐数据 */ diff --git a/app/src/main/res/layout/item_user_nutrition.xml b/app/src/main/res/layout/item_user_nutrition.xml index a4387ac..3b444ba 100644 --- a/app/src/main/res/layout/item_user_nutrition.xml +++ b/app/src/main/res/layout/item_user_nutrition.xml @@ -76,7 +76,7 @@ @dimen/dp53 - 10dp + 0dp true fitXY