支付完成倒计时3秒返回首页;秤默认置零取消,打开直接识别物品;人脸识别图片显示拉伸优化;设置页面切换是否收费模式首页逻辑处理;

This commit is contained in:
2025-12-18 18:25:15 +08:00
parent 1d0e1a62e2
commit ab3109f36a
26 changed files with 540 additions and 258 deletions
@@ -9,11 +9,14 @@ import android.graphics.Point
import android.hardware.Camera
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.util.DisplayMetrics
import android.view.Display
import android.view.View
import android.view.ViewGroup
import android.view.ViewOutlineProvider
import android.view.ViewTreeObserver
import android.widget.FrameLayout
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
@@ -102,6 +105,10 @@ class MainScreenPresentation(
private var lastFaceTrackId: Int = -1 // 上一次的人脸信息
var mealPickupMode: Int = 0 // 取餐模式 0 即放即取 1 余量取餐
var isKeepFaceState = true
var currentUserId: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = PresentationMainScreenBinding.inflate(layoutInflater)
@@ -161,10 +168,10 @@ class MainScreenPresentation(
Timber.tag(TAG).e("updateWeight userNutritionData is null")
return
}
if (dinnerTypeInfo == null) {
Timber.tag(TAG).e("updateWeight dinnerType is null")
return
}
// if (dinnerTypeInfo == null) {
// Timber.tag(TAG).e("updateWeight dinnerType is null")
// return
// }
if (chargeMode == 1) {
//不计费
if (mealPickupMode == 0) {
@@ -270,14 +277,15 @@ class MainScreenPresentation(
}
private fun initView() {
binding.ivRecImage.let {
it.outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setRoundRect(0, 0, view.width, view.height, 12f.dp)
}
}
it.clipToOutline = true
}
// binding.ivRecImage.let {
// it.outlineProvider = object : ViewOutlineProvider() {
// override fun getOutline(view: View, outline: Outline) {
// outline.setRoundRect(0, 0, view.width, view.height, 12f.dp)
// }
// }
// it.clipToOutline = true
// }
binding.ivPreviewImage.visible()
}
override fun onDisplayRemoved() {
@@ -418,6 +426,7 @@ class MainScreenPresentation(
binding.flCameraView.visible()
binding.ivRecImage.gone()
binding.ivPreviewImage.visible()
binding.ivFrame.visible()
binding.ivFaceRecMask.gone()
binding.tvFaceTip.gone()
binding.llPriceInfo.gone()
@@ -467,7 +476,7 @@ class MainScreenPresentation(
binding.ivRecImage.gone()
binding.ivPreviewImage.gone()
binding.ivFrame.gone()
dinnerTypeInfo = null
// userNutritionData = null
userNutrition = null
@@ -476,11 +485,15 @@ class MainScreenPresentation(
stepChangeCallback(currentStep)
currentFood = foodInfo
userViewModel.getDinnerType()
// userViewModel.getDinnerType()
resumeCamera()
}
fun hideRecImage() {
binding.ivRecImage.gone()
}
// 当前食物信息
private var currentFood: FoodInfo? = null
fun updateFood(foodInfo: FoodInfo?) {
@@ -491,11 +504,15 @@ class MainScreenPresentation(
}
binding.tvFoodName.text = foodInfo.foodName
binding.ivPreviewImage.gone()
binding.ivRecImage.let {
it.visible()
val imageUrl =
if (foodInfo.foodImg.isNullOrBlank()) foodInfo.photoUri else foodInfo.foodImg
it.load(imageUrl)
binding.ivFrame.gone()
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
if (chargeMode == 0) {
binding.ivRecImage.let {
it.visible()
val imageUrl =
if (foodInfo.foodImg.isNullOrBlank()) foodInfo.photoUri else foodInfo.foodImg
it.load(imageUrl)
}
}
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
if (mode == 0) {
@@ -537,12 +554,15 @@ class MainScreenPresentation(
}
private fun calculateNutrition(weight1: Double) {
if (currentFood == null || userNutrition == null) {
return
}
var weight = weight1
if (weight < 0) weight = 0.0
debouncer.debounce {
Timber.tag(TAG)
.d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
val dinnerType = dinnerTypeInfo!!.dinnerType!!
val dinnerType = dinnerTypeInfo?.dinnerType
// Timber.tag(TAG)
// .d("calculateNutrition foodName = ${currentFood!!.foodName}, dinnerType = $dinnerType, userId = ${userNutritionData!!.userId}")
val energy: UserEnergy = UserNutritionUtils.calculateNutrition2(
@@ -550,7 +570,7 @@ class MainScreenPresentation(
// userNutritionData!!,
userNutrition!!,
weight,
dinnerType = dinnerType
dinnerType = dinnerType ?: ""
)
// Timber.tag(TAG).d("calculateNutrition calcResultInfo = $calcResultInfo")
// val columnMax = UserNutritionUtils.getMaxInt(calcResultInfo)
@@ -568,14 +588,15 @@ class MainScreenPresentation(
// 设置热量---------------------------------------------------------------------
val calorieArray = doubleArrayOf(
0.0,
userNutrition?.minCalorie?:0.0,
userNutrition?.recommendCalorie?:0.0,
((userNutrition?.recommendCalorie?:0.0) + (userNutrition?.maxCalorie?:0.0))/2,
userNutrition?.maxCalorie?:0.0,
)
userNutrition?.minCalorie ?: 0.0,
userNutrition?.recommendCalorie ?: 0.0,
((userNutrition?.recommendCalorie ?: 0.0) + (userNutrition?.maxCalorie
?: 0.0)) / 2,
userNutrition?.maxCalorie ?: 0.0,
)
val calorieIndex = UserNutritionUtils.findCalorieIndex(energy.grain, calorieArray)
include.customKcalColumn.setImageDrawable(true, calorieIndex)
var maxKcal = userNutrition?.maxCalorie?:1.0
include.customKcalColumn.setImageDrawable(true, calorieIndex)
var maxKcal = userNutrition?.maxCalorie ?: 1.0
Timber.tag(TAG).d("maxKcal = $maxKcal")
// 避免0作为被除数
if (maxKcal <= 0.0) {
@@ -585,9 +606,9 @@ class MainScreenPresentation(
include.totalKcalTv.text = totalKcal.format2String(2)
var totalKcalHeight = (totalKcal / maxKcal).toFloat()
if (totalKcalHeight == 0F) {
include.divKcalView.visibility = View.VISIBLE
include.divKcalView.visible()
} else {
include.divKcalView.visibility = View.GONE
include.divKcalView.gone()
totalKcalHeight += 0.1F
}
include.customKcalColumn.setCustomHeightPercent(totalKcalHeight, true)
@@ -603,9 +624,9 @@ class MainScreenPresentation(
include.totalFoodTv.text = grain.format2String(2)
var grainHeight = (grain / columnMax).toFloat()
if (grainHeight == 0F) {
include.divTotalFoodView.visibility = View.VISIBLE
include.divTotalFoodView.visible()
} else {
include.divTotalFoodView.visibility = View.GONE
include.divTotalFoodView.gone()
grainHeight += 0.1F
}
include.customFoodColumn.setCustomHeightPercent(grainHeight, true)
@@ -616,15 +637,16 @@ class MainScreenPresentation(
mid = userNutrition?.fruitsVegetablesNearExcess,
right = userNutrition?.fruitsVegetablesExcess
)
val fruitsIndex = UserNutritionUtils.findCalorieIndex(energy.fruitsVegetables, fruitsArray)
val fruitsIndex =
UserNutritionUtils.findCalorieIndex(energy.fruitsVegetables, fruitsArray)
include.customVegetableColumn.setImageDrawable(false, fruitsIndex)
include.totalVegetableTv.text = fruitsVegetables.format2String(2)
var fruitsHeight = (fruitsVegetables / columnMax).toFloat()
if (fruitsHeight == 0F) {
include.divVegetableView.visibility = View.VISIBLE
include.divVegetableView.visible()
} else {
include.divVegetableView.visibility = View.GONE
include.divVegetableView.gone()
fruitsHeight += 0.1F
}
include.customVegetableColumn.setCustomHeightPercent(fruitsHeight, true)
@@ -635,14 +657,15 @@ class MainScreenPresentation(
mid = userNutrition?.meatEggsNearExcess,
right = userNutrition?.meatEggsExcess
)
val meatEggsIndex = UserNutritionUtils.findCalorieIndex(energy.meatEggs, meatEggsArray)
val meatEggsIndex =
UserNutritionUtils.findCalorieIndex(energy.meatEggs, meatEggsArray)
include.customMeatColumn.setImageDrawable(false, meatEggsIndex)
include.totalMeatTv.text = meatEggs.format2String(2)
var meatHeight = (meatEggs / columnMax).toFloat()
if (meatHeight == 0F) {
include.divMeatView.visibility = View.VISIBLE
include.divMeatView.visible()
} else {
include.divMeatView.visibility = View.GONE
include.divMeatView.gone()
meatHeight += 0.1F
}
include.customMeatColumn.setCustomHeightPercent(meatHeight, true)
@@ -738,6 +761,9 @@ class MainScreenPresentation(
recognizeViewModel.recognizeUserId.observe(
activity,
Observer { compareResult: CompareResult ->
activity.runOnUiThread {
activity.showWaitingDialog("加载中,请稍后……")
}
Timber.tag(TAG)
.i("recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}")
recognitionTime = System.currentTimeMillis()
@@ -745,6 +771,16 @@ class MainScreenPresentation(
lastFaceTrackId = compareResult.trackId
val faceEntity = compareResult.faceEntity
val userId = faceEntity.userName
currentUserId = userId
// if (TextUtils.equals(userId, "2")) {
// //解决识别出现recognizeStatus = 2待重试的问题
// activity.runOnUiThread {
// ToastUtils.showToast("一开始就在屏幕内发现无法识别,从屏幕外进入就可以识别")
// activity.hideWaitingDialog()
// }
// //userViewModel.getUserFaceCache()
// return@Observer
// }
if (userId == null) return@Observer
//ToastUtils.showToast("人脸识别成功,userId = $userId")
if (currentFood == null) {
@@ -752,6 +788,7 @@ class MainScreenPresentation(
}
if (currentFood == null) {
activity.runOnUiThread {
activity.hideWaitingDialog()
ToastUtils.showToast("请选择菜品")
return@runOnUiThread
}
@@ -761,12 +798,21 @@ class MainScreenPresentation(
userViewModel.getUserNutritionData(userId = userId) { nutrition ->
activity.runOnUiThread {
if (nutrition == null) {
activity.hideWaitingDialog()
ToastUtils.showToast("未查询到营养数据")
return@runOnUiThread
}
this@MainScreenPresentation.userNutrition = nutrition
loadUnbilledMode()
// -------------------------------
val imageUrl =
if (currentFood!!.foodImg.isNullOrBlank()) currentFood!!.photoUri else currentFood!!.foodImg
binding.ivRecImage.let {
it.visible()
it.load(imageUrl)
}
activity.updateImage(imageUrl)
activity.hideWaitingDialog()
}
}
})
@@ -816,7 +862,7 @@ class MainScreenPresentation(
// layoutParams.width = (measuredHeight * ratio).toInt()
// }
// if (scale < 1f) {
// val rgbParam = rgbPreview.getLayoutParams()
// val rgbParam = rgbPreview.layoutParams
// layoutParams.width = (rgbParam.width * scale).toInt()
// layoutParams.height = (rgbParam.height * scale).toInt()
// } else {
@@ -838,16 +884,23 @@ class MainScreenPresentation(
// layoutParams.height = (layoutParams.height / viewRatio).toInt()
// }
// Timber.tag(TAG).d("initRgbCamera:metrics(${metrics.widthPixels},${metrics.heightPixels})")
val layoutParams = previewView.layoutParams
// layoutParams.width = (608.dp * 1.5).roundToInt()
// layoutParams.height = (456.dp * 1.5).roundToInt()
// layoutParams.width = (600.dp * 1.5).roundToInt()
// layoutParams.height = (450.dp * 1.5).roundToInt()
layoutParams.width = 1024
layoutParams.height = 768
//val layoutParams = previewView.layoutParams
//layoutParams.width = 1024
//layoutParams.height = 768
// val w = 600.dp //(912.dp * scale).toInt()
// val h = 900.dp //684.dp
val w = 500.dp
val h = 850.dp
//(1024*scale).toInt()
val layoutParams = FrameLayout.LayoutParams(w, h);
// val layoutParams = FrameLayout.LayoutParams(480, 320);
// val layoutParams = FrameLayout.LayoutParams(912.dp, 684.dp);
previewView.setLayoutParams(layoutParams)
faceRectView.setLayoutParams(layoutParams)
return layoutParams
}
@@ -865,8 +918,11 @@ class MainScreenPresentation(
val previewSizeRgb = camera.getParameters().getPreviewSize()
val layoutParams = adjustPreviewViewSize(
binding.dualCameraTexturePreviewRgb,
binding.dualCameraTexturePreviewRgb, binding.dualCameraFaceRectView,
previewSizeRgb, displayOrientation, 0.6F
binding.dualCameraTexturePreviewRgb,
binding.dualCameraFaceRectView,
previewSizeRgb, displayOrientation,
0.5F
//0.6F
)
Timber.tag(TAG)
@@ -886,10 +942,8 @@ class MainScreenPresentation(
)
// 调整识别窗口位置
rgbFaceRectTransformer = FaceRectTransformer(
// previewSizeRgb.width,
// previewSizeRgb.height,
layoutParams.width,
layoutParams.height,
previewSizeRgb.width,
previewSizeRgb.height,
layoutParams.width,
layoutParams.height,
90,
@@ -945,9 +999,12 @@ class MainScreenPresentation(
val previewConfig: PreviewConfig = recognizeViewModel.previewConfig
rgbCameraHelper = DualCameraHelper.Builder()
.previewViewSize(Point(measuredWidth, measuredHeight))
// .previewViewSize(Point(608.dp, 456.dp))
// .previewViewSize(Point(1024, 768))
.rotation(activity.windowManager.defaultDisplay.rotation)
.additionalRotation(previewConfig.rgbAdditionalDisplayOrientation) // 角度
.previewSize(recognizeViewModel.loadPreviewSize())
// .previewSize(Point(1080, 720))
.specificCameraId(previewConfig.rgbCameraId)
.isMirror(true)
.previewOn(binding.dualCameraTexturePreviewRgb)
@@ -982,9 +1039,10 @@ class MainScreenPresentation(
)
irFaceRectTransformer = FaceRectTransformer(
// previewSizeIr.width, previewSizeIr.height,
previewSizeIr.width, previewSizeIr.height,
// layoutParams.width, layoutParams.height,
layoutParams.width, layoutParams.height,
layoutParams.width, layoutParams.height, displayOrientation, cameraId, isMirror,
displayOrientation, cameraId, isMirror,
ConfigUtil.isDrawIrRectHorizontalMirror(context),
ConfigUtil.isDrawIrRectVerticalMirror(context)
)
@@ -1027,6 +1085,7 @@ class MainScreenPresentation(
binding.dualCameraTexturePreviewIr.measuredHeight
)
)
// .previewViewSize(Point(133,100))
.rotation(activity.windowManager.defaultDisplay.rotation)
.specificCameraId(previewConfig.irCameraId)
.previewOn(binding.dualCameraTexturePreviewIr)
@@ -1064,16 +1123,17 @@ class MainScreenPresentation(
Timber.tag(TAG)
.d("listIsEmpty=$listIsEmpty,lastFaceTrackId=$lastFaceTrackId,listFirstTrackId=$listFirstTrackId")
if (listIsEmpty || (lastFaceTrackId != listFirstTrackId)) {
if (lastFaceTrackId != -1) {
if (lastFaceTrackId != -1 && currentUserId!=null) {
mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
Timber.tag(TAG).i("$lastFaceTrackId 用户离开")
lastFaceTrackId = -1
postUserData()
if (mealPickupMode == 0) {
if (mealPickupMode == 1 || isKeepFaceState) {
step2FaceRecognizing(currentFood!!)
isKeepFaceState = false
} else {
activity.isAnalyzing = false
step1FoodRecognizing()
} else {
step2FaceRecognizing(currentFood!!)
}
}
}
@@ -1115,7 +1175,40 @@ class MainScreenPresentation(
if (MyApp.DEBUG) {
ToastUtils.showToast("订单已生成")
}
currentUserId = null
}
}
fun hideNutritionView(chargeMode: Int) {
binding.nutritionInclude.root.gone()
binding.calorieInclude.root.gone()
binding.tvFoodRecPrompt.visible()
binding.ivRecImage.gone()
binding.llPriceInfo.gone()
binding.ivPreviewImage.visible()
binding.ivFrame.visible()
// if (chargeMode == 1) {
// //不计费
//// binding.flFace.visible()
// binding.ivRecImage.gone()
// binding.llPriceInfo.gone()
// binding.ivPreviewImage.gone()
// binding.ivFrame.gone()
// } else {
// //计费
// binding.flFace.gone()
// binding.llPriceInfo.gone()
//// val imageUrl = if (currentFood!!.foodImg.isNullOrBlank()) currentFood!!.photoUri else currentFood!!.foodImg
//// binding.ivRecImage.let {
//// it.visible()
//// it.load(imageUrl)
//// }
// binding.ivRecImage.gone()
// binding.ivPreviewImage.visible()
// binding.ivFrame.visible()
// }
}
}