优化
This commit is contained in:
@@ -40,7 +40,8 @@
|
||||
</receiver>
|
||||
<activity
|
||||
android:name=".activity.InitActivity"
|
||||
android:exported="true">
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -51,15 +52,18 @@
|
||||
android:name=".activity.MainActivity"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.FoodCollectionActivity"
|
||||
android:exported="true">
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".activity.FoodCollectionActivity"-->
|
||||
<!-- android:exported="true">-->
|
||||
|
||||
</activity>
|
||||
<activity android:name="com.sw.dualscreen.activity.CollectedDataActivity" />
|
||||
<activity android:name="com.sw.dualscreen.activity.SettingActivity" />
|
||||
<activity android:name="com.sw.dualscreen.activity.CollectedFoodActivity" />
|
||||
<activity android:name="com.sw.dualscreen.activity.PayActivity" />
|
||||
<!-- </activity>-->
|
||||
<!-- <activity android:name="com.sw.dualscreen.activity.CollectedDataActivity" />-->
|
||||
<activity android:name="com.sw.dualscreen.activity.SettingActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||
<activity android:name="com.sw.dualscreen.activity.CollectedFoodActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||
<activity android:name="com.sw.dualscreen.activity.PayActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.sw.dualscreen.activity
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.Display
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
@@ -13,19 +13,17 @@ import android.widget.TextView
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.sw.dualscreen.R
|
||||
import com.sw.dualscreen.databinding.DialogWaitingBinding
|
||||
import com.sw.dualscreen.model.IActivityResult
|
||||
import com.sw.dualscreen.model.response.PostEvent
|
||||
import com.sw.dualscreen.view.CustomDialog
|
||||
import com.sw.dualscreen.viewmodel.BaseViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import com.sw.plate.utils.ToastUtils
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import timber.log.Timber
|
||||
|
||||
|
||||
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
|
||||
@@ -84,17 +82,14 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
/**
|
||||
* 显示等待提示框
|
||||
*/
|
||||
fun showWaitingDialog(tip: String?){
|
||||
fun showWaitingDialog(tip: String?) {
|
||||
runOnUiThread {
|
||||
hideWaitingDialog()
|
||||
val view = View.inflate(this, R.layout.dialog_waiting, null)
|
||||
if (!TextUtils.isEmpty(tip)) (view.findViewById<View?>(R.id.tvTip) as TextView).text =
|
||||
tip
|
||||
mDialogWaiting = CustomDialog(this, view, R.style.MyDialog).apply {
|
||||
setCancelable(true)
|
||||
setCanceledOnTouchOutside(true)
|
||||
show()
|
||||
}
|
||||
//val view = View.inflate(this, R.layout.dialog_waiting, null)
|
||||
val dialogBinding = DialogWaitingBinding.inflate(LayoutInflater.from(this))
|
||||
dialogBinding.tvTip.text = tip
|
||||
mDialogWaiting = CustomDialog(this, dialogBinding.root)
|
||||
mDialogWaiting?.show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,8 +108,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
hideWaitingDialog()
|
||||
val view = View.inflate(this, R.layout.dialog_waiting, null)
|
||||
mDialogWaiting = CustomDialog(this, view, R.style.MyDialog)
|
||||
mDialogWaiting!!.show()
|
||||
mDialogWaiting!!.setCancelable(true)
|
||||
mDialogWaiting?.show()
|
||||
}
|
||||
val contentView = mDialogWaiting?.findViewById<ViewGroup>(android.R.id.content)
|
||||
val tvTip = contentView?.findViewById<TextView>(R.id.tvTip)
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.sw.dualscreen.ext.gone
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.ext.visible
|
||||
import com.sw.dualscreen.model.response.ChargeModeEvent
|
||||
import com.sw.dualscreen.model.response.ClickBackEvent
|
||||
import com.sw.dualscreen.model.response.FoodInfo
|
||||
import com.sw.dualscreen.model.response.FoodOrder
|
||||
import com.sw.dualscreen.model.response.PaySuccessEvent
|
||||
@@ -114,6 +115,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
private var isRecognitionFood = true
|
||||
private var isFirstOpen = true
|
||||
|
||||
private var isStartRecognize = false
|
||||
|
||||
override fun getViewModel(): BaseViewModel {
|
||||
return viewModel
|
||||
}
|
||||
@@ -240,17 +243,23 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
pauseAnalysis()
|
||||
recognizeWeight = lastWeight
|
||||
Timber.tag(TAG)
|
||||
.d("registerDataChange,副屏updateFood调用前耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
presentation?.updateFood(foodInfo)
|
||||
binding.tvFoodName.text = foodInfo.foodName
|
||||
binding.previewView.gone()
|
||||
binding.ivImg.visible()
|
||||
if (foodInfo.foodImg.isNullOrBlank()) {
|
||||
takePhoto { imgUri ->
|
||||
takePhoto(successCallback = { imgUri ->
|
||||
binding.ivImg.load(imgUri)
|
||||
presentation?.updateFood(foodInfo.copy(foodImg = imgUri.toString()))
|
||||
}
|
||||
}, failureCallback = {
|
||||
|
||||
})
|
||||
} else {
|
||||
binding.ivImg.load(foodInfo.foodImg)
|
||||
}
|
||||
binding.ivImg.load(foodInfo.foodImg ?: foodInfo.photoUri)
|
||||
//pauseAnalysis()
|
||||
}
|
||||
|
||||
@@ -283,6 +292,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
SensorScaleUtils.addWeightListener { weight ->
|
||||
Timber.d("registerDataChange weight = $weight")
|
||||
if (isPageVisible.not() || isStartRecognize.not()) return@addWeightListener
|
||||
val isWeightChange = weight - lastWeight > 0.05
|
||||
recognizeByWeight(weight, isWeightChange)
|
||||
}
|
||||
@@ -308,15 +318,23 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
lastWeight = weight
|
||||
}
|
||||
|
||||
private var startTime = 0L
|
||||
|
||||
fun recognizeFood() {
|
||||
startTime = System.currentTimeMillis()
|
||||
LightManager.openRedLight()
|
||||
LightManager.openGreenLight()
|
||||
takePhoto { photoUri ->
|
||||
showWaitingDialog("识别中,请稍后……")
|
||||
takePhoto(successCallback = { photoUri ->
|
||||
lastPhotoUri = photoUri
|
||||
Timber.tag(TAG).d("main,takePhoto耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
Timber.d("registerDataChange photoUri = ${photoUri.path}")
|
||||
// viewModel.getIdentifiedFoodList()
|
||||
|
||||
ImageUtil.uriToBitmap(this, photoUri)?.let { bitmap ->
|
||||
Timber.tag(TAG).d("main,uriToBitmap耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
Timber.d("registerDataChange photoUri 拿到bitmap")
|
||||
// val bmp = BitmapCropper.cropCenter(bitmap, 1300, 900)
|
||||
Timber.d("registerDataChange photoUri bitmap裁剪完成")
|
||||
@@ -325,19 +343,21 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
this,
|
||||
"IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
Timber.tag(TAG)
|
||||
.d("main,saveToAppFilesDir耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
Timber.d("registerDataChange photoUri bitmap保存文件路径:${file?.absolutePath}")
|
||||
//val nameList = FoodModule.queryFood(bitmap)
|
||||
val scoreList = FoodModule.getFoodScoreList(bitmap)
|
||||
Timber.d(
|
||||
"registerDataChange photoUri 拿到识别数据:${
|
||||
GsonUtils.toJson(
|
||||
scoreList
|
||||
)
|
||||
}"
|
||||
)
|
||||
val recDataJson = GsonUtils.toJson(scoreList)
|
||||
Timber.tag(TAG)
|
||||
.d("main,getFoodScoreList耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
Timber.d("registerDataChange photoUri 拿到识别数据:$recDataJson")
|
||||
val nameList = scoreList.map { it.name }
|
||||
val foodName = nameList.joinToString(separator = ",")
|
||||
|
||||
hideWaitingDialog()
|
||||
Timber.d("registerDataChange photoUri 识别数据名称:$foodName")
|
||||
if (TextUtils.isEmpty(foodName)) {
|
||||
LightManager.closeGreenLight()
|
||||
@@ -350,15 +370,28 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
} else {
|
||||
//binding.layoutRescan.visibility = View.GONE
|
||||
showWaitingDialog("正在查询菜品信息,请稍后……")
|
||||
viewModel.getFoodInfo(foodName) { list ->
|
||||
runOnUiThread {
|
||||
hideWaitingDialog()
|
||||
Timber.tag(TAG)
|
||||
.d("main,getFoodInfo耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
updateFoodInfo(list.toMutableList(), scoreList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}, failureCallback = {
|
||||
runOnUiThread {
|
||||
hideWaitingDialog()
|
||||
ToastUtils.showToast("拍照异常,请手动放置后重新识别")
|
||||
}
|
||||
// binding.root.postDelayed({
|
||||
// recognizeFood()
|
||||
// }, 500)
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
@@ -447,6 +480,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
if (isAnalyzing) {
|
||||
val bitmap = imageProxy.toBitmap()
|
||||
presentation?.updateImage(bitmap) // 更新副屏
|
||||
isStartRecognize = true
|
||||
}
|
||||
imageProxy.close() // 必须关闭以释放资源
|
||||
}
|
||||
@@ -518,7 +552,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
|
||||
// 拍照功能
|
||||
private fun takePhoto(callback: (Uri) -> Unit) {
|
||||
private fun takePhoto(successCallback: (Uri) -> Unit, failureCallback: () -> Unit) {
|
||||
Timber.d("takePhoto")
|
||||
// 临时停止分析以避免干扰
|
||||
isAnalyzing = false
|
||||
@@ -545,7 +579,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
Timber.d("takePhoto savedUri = $savedUri")
|
||||
// ToastUtils.showToast("照片保存成功: $savedUri")
|
||||
if (savedUri != null) {
|
||||
callback(savedUri)
|
||||
successCallback(savedUri)
|
||||
}
|
||||
}
|
||||
// 恢复图像分析
|
||||
@@ -554,6 +588,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
override fun onError(exception: ImageCaptureException) {
|
||||
Timber.e("拍照失败: ${exception.message}")
|
||||
failureCallback()
|
||||
//runOnUiThread {
|
||||
// ToastUtils.showToast("拍照失败: ${exception.message}")
|
||||
//}
|
||||
@@ -631,14 +666,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.tvTitleTime.text = dateTime
|
||||
}
|
||||
|
||||
private var isPageVisible = true
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
Timber.tag("onResume").d("=================onResume================")
|
||||
isPageVisible = true
|
||||
// 启动定时器
|
||||
handler.postDelayed(timeoutRunnable, TIME_OUT)
|
||||
|
||||
if (isFirstOpen) {
|
||||
//首次
|
||||
//首次
|
||||
setupSecondaryDisplay()
|
||||
presentation?.step1FoodRecognizing()
|
||||
isFirstOpen = false
|
||||
@@ -650,11 +687,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
setupSecondaryDisplay()
|
||||
presentation?.step1FoodRecognizing()
|
||||
} else {
|
||||
//已显示副屏,则进行更新
|
||||
val weight = lastWeight
|
||||
lastWeight = 0.0
|
||||
presentation?.hideRecImage()
|
||||
recognizeByWeight(weight, true)
|
||||
if (isRefreshPage) {
|
||||
//已显示副屏,则进行更新
|
||||
val weight = lastWeight
|
||||
lastWeight = 0.0
|
||||
presentation?.hideRecImage()
|
||||
recognizeByWeight(weight, true)
|
||||
}
|
||||
isRefreshPage = !isRefreshPage
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,6 +714,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
isPageVisible = false
|
||||
// 取消定时器
|
||||
handler.removeCallbacks(timeoutRunnable)
|
||||
}
|
||||
@@ -770,16 +811,24 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onPaySuccessEvent(event: PaySuccessEvent) {
|
||||
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)?:0
|
||||
isRefreshPage = true
|
||||
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0) ?: 0
|
||||
presentation?.hideNutritionView(chargeMode)
|
||||
presentation?.cancel()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onChargeModeEvent(event: ChargeModeEvent) {
|
||||
isRefreshPage = true
|
||||
isStartRecognize = false
|
||||
presentation?.hideNutritionView(event.chargeMode)
|
||||
// presentation?.cancel()
|
||||
}
|
||||
private var isRefreshPage = false
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onClickBackEvent(event: ClickBackEvent) {
|
||||
isRefreshPage = false
|
||||
}
|
||||
|
||||
private fun clickPayButton() {
|
||||
if (checkedItem == null) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.sw.dualscreen.activity
|
||||
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.sw.dualscreen.R
|
||||
@@ -7,8 +8,10 @@ import com.sw.dualscreen.activity.fragment.BusinessFragment
|
||||
import com.sw.dualscreen.activity.fragment.CollectFragment
|
||||
import com.sw.dualscreen.databinding.ActivitySettingBinding
|
||||
import com.sw.dualscreen.model.response.FoodInfo
|
||||
import com.sw.dualscreen.model.response.ClickBackEvent
|
||||
import com.sw.dualscreen.viewmodel.BaseViewModel
|
||||
import com.sw.dualscreen.viewmodel.UserViewModel
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class SettingActivity : BaseActivity<ActivitySettingBinding>() {
|
||||
|
||||
@@ -28,10 +31,12 @@ class SettingActivity : BaseActivity<ActivitySettingBinding>() {
|
||||
|
||||
override fun initialize() {
|
||||
super.initialize()
|
||||
initBackDispatcher()
|
||||
binding.include.let {
|
||||
it.ivPageBack.setOnClickListener {
|
||||
// val intent = Intent(this, MainActivity::class.java)
|
||||
// startActivity(intent)
|
||||
EventBus.getDefault().post(ClickBackEvent())
|
||||
finish()
|
||||
}
|
||||
it.tvPageTitle.text = "设置"
|
||||
@@ -65,4 +70,17 @@ class SettingActivity : BaseActivity<ActivitySettingBinding>() {
|
||||
viewModel.searchByFoodName(foodName, action)
|
||||
}
|
||||
|
||||
private lateinit var backPressedCallback: OnBackPressedCallback
|
||||
private fun initBackDispatcher() {
|
||||
// 创建回调,true表示初始启用状态
|
||||
backPressedCallback = object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
EventBus.getDefault().post(ClickBackEvent())
|
||||
}
|
||||
}
|
||||
// 注册回调,使用lifecycleOwner确保生命周期安全
|
||||
onBackPressedDispatcher.addCallback(this, backPressedCallback)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -45,8 +45,9 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "CollectFragment"
|
||||
const val MAX_COUNT = 102
|
||||
const val MAX_COUNT = 15
|
||||
}
|
||||
|
||||
private var selectedFoodId: String? = ""
|
||||
private var selectedFoodName: String? = ""
|
||||
|
||||
@@ -58,17 +59,17 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
}
|
||||
|
||||
private val searchFoodList = mutableListOf<FoodInfo>()
|
||||
private var settingActivity: SettingActivity?=null
|
||||
private var settingActivity: SettingActivity? = null
|
||||
private var checkedItem: FoodInfo? = null
|
||||
private val searchFoodAdapter by lazy {
|
||||
SearchFoodAdapter(searchFoodList).apply {
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
checkedItem = searchFoodList[position]
|
||||
selectedFoodId = checkedItem!!.foodId
|
||||
selectedFoodName = checkedItem!!.foodName
|
||||
val isChecked = checkedItem!!.isChecked
|
||||
searchFoodList[position].isChecked = isChecked.not()
|
||||
notifyItemChanged(position)
|
||||
selectedFoodId = checkedItem!!.foodId
|
||||
selectedFoodName = checkedItem!!.foodName
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,6 +86,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
it.bitmap = null
|
||||
it.imageVector = null
|
||||
it.imageFile = null
|
||||
it.imageUri = null
|
||||
it.isShowCamera = true
|
||||
it.isFinish = false
|
||||
it.uploadSuccess = false
|
||||
@@ -93,6 +95,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun inflateViewBinding(): FragmentCollectBinding {
|
||||
return FragmentCollectBinding.inflate(LayoutInflater.from(context))
|
||||
}
|
||||
@@ -104,14 +107,25 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
if (index == -1) {
|
||||
ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
|
||||
settingActivity?.hideWaitingDialog()
|
||||
rerurn@cameraCallback
|
||||
rerurn@ cameraCallback
|
||||
}
|
||||
activity?.runOnUiThread {
|
||||
foodCollectionList[index].let {
|
||||
it.imageVector = null
|
||||
it.bitmap = null
|
||||
it.isShowCamera = false
|
||||
it.imageFile = null
|
||||
it.imageUri = uri
|
||||
}
|
||||
collectionAdapter.notifyItemChanged(index)
|
||||
}
|
||||
// settingActivity?.hideWaitingDialog()
|
||||
ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap ->
|
||||
// val cropBitmap = BitmapCropper.cropCenter(
|
||||
// original = bitmap,
|
||||
// targetWidth = 1300, targetHeight = 900,
|
||||
// //offsetX = 30, offsetY = 100
|
||||
// )
|
||||
// val cropBitmap = BitmapCropper.cropCenter(
|
||||
// original = bitmap,
|
||||
// targetWidth = 1300, targetHeight = 900,
|
||||
// //offsetX = 30, offsetY = 100
|
||||
// )
|
||||
initBox()
|
||||
val imageVector = try {
|
||||
FoodModule.bitmap2FloatArray(bitmap)
|
||||
@@ -154,7 +168,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
}
|
||||
settingActivity?.showWaitingDialog("拍照中……")
|
||||
cameraUtils.takePhoto(cameraCallback) { errMsg ->
|
||||
ToastUtils.showToast(errMsg)
|
||||
ToastUtils.showToast("拍照异常,请重新操作")
|
||||
settingActivity?.hideWaitingDialog()
|
||||
}
|
||||
}
|
||||
@@ -173,7 +187,8 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
cameraUtils.setPreviewController(previewView)
|
||||
|
||||
binding.rvFoodList.let {
|
||||
it.layoutManager = GridLayoutManager(requireActivity(), 3, GridLayoutManager.VERTICAL, false)
|
||||
it.layoutManager =
|
||||
GridLayoutManager(requireActivity(), 3, GridLayoutManager.VERTICAL, false)
|
||||
it.adapter = collectionAdapter
|
||||
}
|
||||
|
||||
@@ -182,12 +197,12 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
}
|
||||
|
||||
binding.btnSave.setOnClickListener {
|
||||
if (selectedFoodName.isNullOrBlank()) {
|
||||
Toast.makeText(requireActivity(), "请选择菜品名称", Toast.LENGTH_SHORT).show()
|
||||
if (checkedItem == null || checkedItem!!.isChecked.not()) {
|
||||
ToastUtils.showToast("请选择菜品名称")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (foodCollectionList.size <= 1) {
|
||||
Toast.makeText(requireActivity(), "请拍摄菜品照片", Toast.LENGTH_SHORT).show()
|
||||
ToastUtils.showToast("请拍摄菜品照片")
|
||||
return@setOnClickListener
|
||||
}
|
||||
upload()
|
||||
@@ -235,9 +250,12 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
//params["foodVector"] = foodVector.toRequestBody()
|
||||
ImageUploader(
|
||||
totalList = foodCollectionList,
|
||||
uploadImage = { batch->
|
||||
uploadImage = { batch ->
|
||||
val files = batch.map { it.imageFile }
|
||||
(requireActivity() as SettingActivity).viewModel.uploadCollectFoodPics(files,params)
|
||||
(requireActivity() as SettingActivity).viewModel.uploadCollectFoodPics(
|
||||
files,
|
||||
params
|
||||
)
|
||||
},
|
||||
onProgress = { count, batch ->
|
||||
activity?.runOnUiThread {
|
||||
@@ -347,6 +365,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
it.bitmap = null
|
||||
it.imageVector = null
|
||||
it.imageFile = null
|
||||
it.imageUri = null
|
||||
it.isShowCamera = true
|
||||
it.isFinish = false
|
||||
it.uploadSuccess = false
|
||||
|
||||
@@ -39,7 +39,11 @@ class FoodCollectionAdapter (var list: MutableList<FoodCollectionBean>) :
|
||||
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
//setImageURI(it.imageUri)
|
||||
//setImageBitmap(it.bitmap)
|
||||
load(it.imageFile)
|
||||
if (it.imageUri!=null) {
|
||||
setImageURI(it.imageUri)
|
||||
} else {
|
||||
load(it.imageFile)
|
||||
}
|
||||
// it.bitmap?.let { bitmap ->
|
||||
// GlideUtils.loadRoundCornerWitBitmap(
|
||||
// context,
|
||||
|
||||
@@ -126,4 +126,8 @@ data class PaySuccessEvent(
|
||||
|
||||
data class ChargeModeEvent(
|
||||
var chargeMode:Int = 0
|
||||
)
|
||||
|
||||
data class ClickBackEvent(
|
||||
var name: String = ""
|
||||
)
|
||||
@@ -19,6 +19,7 @@ data class FoodClassInfo(
|
||||
|
||||
data class FoodCollectionBean(
|
||||
var imageFile: File? = null,
|
||||
var imageUri: Uri? = null,
|
||||
var bitmap: Bitmap? = null,
|
||||
var imageVector: FloatArray? = null,
|
||||
var isShowCamera: Boolean = false,
|
||||
|
||||
@@ -92,6 +92,7 @@ object FoodModule {
|
||||
}
|
||||
|
||||
fun queryFoodNameScore(floatArray: FloatArray, queryCount: Int = 15): List<IdNameScore> {
|
||||
val startTime = System.currentTimeMillis()
|
||||
val query: Query<Food> =
|
||||
box.query(Food_.foodVector.nearestNeighbors(floatArray, queryCount)).build()
|
||||
//查询比较分数
|
||||
@@ -101,11 +102,14 @@ object FoodModule {
|
||||
idScoreList.forEach {
|
||||
nameScoreList.add(IdNameScore(id = it.id, name = box.get(it.id).name?:"", score = it.score))
|
||||
}
|
||||
Timber.tag("FoodModule").d("registerDataChange,queryFood数据:${GsonUtils.toJson(nameScoreList)}")
|
||||
val nameScoreData = GsonUtils.toJson(nameScoreList)
|
||||
Timber.tag("FoodModule").d("registerDataChange,queryFood,耗时:${System.currentTimeMillis()-startTime},数据:$nameScoreData")
|
||||
return nameScoreList
|
||||
}
|
||||
fun getFoodScoreList(bitmap: Bitmap, queryCount: Int = 15): List<IdNameScore> {
|
||||
val startTime = System.currentTimeMillis()
|
||||
val floatArray = bitmap2FloatArray(bitmap)
|
||||
Timber.tag("FoodModule").d("registerDataChange,bitmap2FloatArray,耗时:${System.currentTimeMillis()-startTime}")
|
||||
val nameScoreList = queryFoodNameScore(floatArray, queryCount)
|
||||
if (nameScoreList.isEmpty()) {
|
||||
return emptyList()
|
||||
|
||||
@@ -118,6 +118,7 @@ class MainScreenPresentation(
|
||||
initView()
|
||||
setupArcCamera()
|
||||
registerDataChange()
|
||||
startTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
private var isFirstGetWeight = true
|
||||
@@ -261,19 +262,34 @@ class MainScreenPresentation(
|
||||
/**
|
||||
* 显示识别出的菜品信息
|
||||
*/
|
||||
fun step3ShowRecognizeResult() {
|
||||
Timber.tag(TAG).d("step3")
|
||||
fun step3ShowRecognizeResult(userId: String) {
|
||||
Timber.tag(TAG).d("main,step3,耗时:${System.currentTimeMillis() - startTime}")
|
||||
LightManager.closeRedLight()
|
||||
LightManager.openGreenLight()
|
||||
currentStep = 3
|
||||
stepChangeCallback(currentStep)
|
||||
if (currentFood == null) {
|
||||
ToastUtils.showToast("选中物品为空")
|
||||
return
|
||||
}
|
||||
// updateFoodInfo(currentFood!!)
|
||||
|
||||
//foodRecSuccess(currentFood!!)
|
||||
//根据接口数据更新热量数据--------------------------
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
@@ -392,14 +408,19 @@ class MainScreenPresentation(
|
||||
calculateNutrition(recognitionWeight - lastWeight)
|
||||
}
|
||||
|
||||
private var isFirstOpen = true
|
||||
var startTime = 0L
|
||||
/**
|
||||
* 餐品识别中
|
||||
*/
|
||||
fun step1FoodRecognizing() {
|
||||
Timber.tag(TAG).d("main,step1,耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
hideStandbyScreen()
|
||||
activity.resetTouchTime()
|
||||
activity.resumeAnalysis()
|
||||
Timber.tag(TAG).d("step1")
|
||||
if (isFirstOpen.not()) {
|
||||
activity.resumeAnalysis()
|
||||
}
|
||||
//if (abs(lastWeight.toInt()) <= 5) {
|
||||
// activity.runOnUiThread {
|
||||
// ToastUtils.showToast("秤上重量几乎为0,请确认")
|
||||
@@ -426,11 +447,11 @@ class MainScreenPresentation(
|
||||
binding.flCameraView.visible()
|
||||
binding.ivRecImage.gone()
|
||||
binding.ivPreviewImage.visible()
|
||||
binding.ivFrame.visible()
|
||||
binding.ivFaceRecMask.gone()
|
||||
binding.tvFaceTip.gone()
|
||||
binding.llPriceInfo.gone()
|
||||
binding.flFace.gone()
|
||||
binding.ivFrame.gone()
|
||||
binding.flRecognizeIr.gone()
|
||||
|
||||
pauseCamera()
|
||||
@@ -458,7 +479,8 @@ class MainScreenPresentation(
|
||||
*/
|
||||
fun step2FaceRecognizing(foodInfo: FoodInfo) {
|
||||
isGoStep1 = true
|
||||
Timber.tag(TAG).d("step2")
|
||||
Timber.tag(TAG).d("main,step2,耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
currentStep = 2
|
||||
LightManager.closeRedLight()
|
||||
|
||||
@@ -497,7 +519,8 @@ class MainScreenPresentation(
|
||||
// 当前食物信息
|
||||
private var currentFood: FoodInfo? = null
|
||||
fun updateFood(foodInfo: FoodInfo?) {
|
||||
Timber.tag(TAG).d("updateFood")
|
||||
Timber.tag(TAG).d("main,updateFood,耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
currentFood = foodInfo
|
||||
if (foodInfo == null) {
|
||||
return
|
||||
@@ -513,6 +536,8 @@ class MainScreenPresentation(
|
||||
if (foodInfo.foodImg.isNullOrBlank()) foodInfo.photoUri else foodInfo.foodImg
|
||||
it.load(imageUrl)
|
||||
}
|
||||
} else {
|
||||
binding.ivRecImage.gone()
|
||||
}
|
||||
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
if (mode == 0) {
|
||||
@@ -793,28 +818,7 @@ class MainScreenPresentation(
|
||||
return@runOnUiThread
|
||||
}
|
||||
}
|
||||
step3ShowRecognizeResult()
|
||||
//根据接口数据更新热量数据--------------------------
|
||||
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()
|
||||
}
|
||||
}
|
||||
step3ShowRecognizeResult(userId)
|
||||
})
|
||||
|
||||
recognizeViewModel.drawRectInfoText.observe(activity, Observer { info ->
|
||||
@@ -1140,10 +1144,9 @@ class MainScreenPresentation(
|
||||
}
|
||||
|
||||
fun postUserData() {
|
||||
Timber.tag(TAG).d("postUserData")
|
||||
if (userNutrition == null || currentFood == null) {
|
||||
Timber.tag(TAG)
|
||||
.d("postUserData userNutritionData = ${userNutrition == null}, currentFood = ${currentFood == null}")
|
||||
Timber.tag(TAG)
|
||||
.d("postUserData userNutritionData是否null: ${userNutrition == null}, currentFood是否null: ${currentFood == null},currentUserId是否null:${currentUserId == null}", )
|
||||
if (userNutrition == null || currentFood == null || currentUserId == null) {
|
||||
return
|
||||
}
|
||||
createOrder()
|
||||
|
||||
@@ -3,14 +3,14 @@ package com.sw.dualscreen.view;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sw.dualscreen.R;
|
||||
|
||||
/**
|
||||
@@ -18,78 +18,86 @@ import com.sw.dualscreen.R;
|
||||
*/
|
||||
public class CustomDialog extends Dialog {
|
||||
|
||||
|
||||
/**
|
||||
* 宽高由布局文件中指定(但是最底层的宽度无效,可以多嵌套一层解决)
|
||||
*/
|
||||
public CustomDialog(Context context, View layout) {
|
||||
super(context, R.style.LoadingDialog);
|
||||
setContentView(layout);
|
||||
initConfig();
|
||||
}
|
||||
|
||||
public CustomDialog(Context context, View layout, int style) {
|
||||
|
||||
super(context, style);
|
||||
|
||||
setContentView(layout);
|
||||
initConfig();
|
||||
}
|
||||
|
||||
private void initConfig() {
|
||||
setCancelable(true);
|
||||
setCanceledOnTouchOutside(true);
|
||||
Window window = getWindow();
|
||||
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
|
||||
params.gravity = Gravity.CENTER;
|
||||
|
||||
window.setAttributes(params);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 宽高由该方法的参数设置
|
||||
*/
|
||||
public CustomDialog(Context context, int width, int height, View layout,
|
||||
int style) {
|
||||
super(context, style);
|
||||
// 设置内容
|
||||
setContentView(layout);
|
||||
// 设置窗口属性
|
||||
Window window = getWindow();
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
// 设置宽度、高度、密度、对齐方式
|
||||
float density = getDensity(context);
|
||||
params.width = (int) (width * density);
|
||||
params.height = (int) (height * density);
|
||||
params.gravity = Gravity.CENTER;
|
||||
window.setAttributes(params);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取显示密度
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public float getDensity(Context context) {
|
||||
Resources res = context.getResources();
|
||||
DisplayMetrics dm = res.getDisplayMetrics();
|
||||
return dm.density;
|
||||
}
|
||||
|
||||
private void fullScreenImmersive(View view) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
view.setSystemUiVisibility(uiOptions);
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
params.gravity = Gravity.CENTER;
|
||||
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
window.setAttributes(params);
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * 宽高由该方法的参数设置
|
||||
// */
|
||||
// public CustomDialog(Context context, int width, int height, View layout,
|
||||
// int style) {
|
||||
// super(context, style);
|
||||
// // 设置内容
|
||||
// setContentView(layout);
|
||||
// // 设置窗口属性
|
||||
// Window window = getWindow();
|
||||
// WindowManager.LayoutParams params = window.getAttributes();
|
||||
// // 设置宽度、高度、密度、对齐方式
|
||||
// float density = getDensity(context);
|
||||
// params.width = (int) (width * density);
|
||||
// params.height = (int) (height * density);
|
||||
// params.gravity = Gravity.CENTER;
|
||||
// window.setAttributes(params);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取显示密度
|
||||
// *
|
||||
// * @param context
|
||||
// * @return
|
||||
// */
|
||||
// public float getDensity(Context context) {
|
||||
// Resources res = context.getResources();
|
||||
// DisplayMetrics dm = res.getDisplayMetrics();
|
||||
// return dm.density;
|
||||
// }
|
||||
//
|
||||
// private void fullScreenImmersive(View view) {
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
// | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
// | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
// | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
// | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
// | View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
// view.setSystemUiVisibility(uiOptions);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
@Override
|
||||
|
||||
public void show() {
|
||||
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
super.show();
|
||||
// fullScreenImmersive(getWindow().getDecorView());
|
||||
// this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
}
|
||||
// @Override
|
||||
// public void show() {
|
||||
// this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
// super.show();
|
||||
//// fullScreenImmersive(getWindow().getDecorView());
|
||||
//// this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -2,5 +2,5 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFFF3232"/>
|
||||
<corners android:radius="6dp"/>
|
||||
<corners android:radius="10dp"/>
|
||||
</shape>
|
||||
@@ -58,7 +58,7 @@
|
||||
android:id="@+id/tv_food_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="60dp"
|
||||
android:layout_marginTop="50dp"
|
||||
android:textStyle="bold"
|
||||
android:textSize="52sp"
|
||||
android:textColor="#FF0A1428"
|
||||
@@ -67,9 +67,9 @@
|
||||
<FrameLayout
|
||||
android:id="@+id/foodDisplayLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="500dp"
|
||||
android:layout_height="560dp"
|
||||
android:layout_marginHorizontal="28dp"
|
||||
android:layout_marginTop="100dp"
|
||||
android:layout_marginTop="80dp"
|
||||
android:visibility="visible">
|
||||
|
||||
<androidx.camera.view.PreviewView
|
||||
@@ -100,6 +100,7 @@
|
||||
android:layout_height="0dp"
|
||||
app:spanCount="2"
|
||||
tools:itemCount="8"
|
||||
android:overScrollMode="never"
|
||||
tools:listitem="@layout/list_item_search_food"
|
||||
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||
android:layout_marginHorizontal="14dp"
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
android:layout_width="39dp"
|
||||
android:layout_height="39dp"
|
||||
android:indeterminateTint="@color/teal_200"
|
||||
android:indeterminateTintMode="src_atop" />
|
||||
android:indeterminateTintMode="src_atop"
|
||||
android:focusable="false"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTip"
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btnConfirm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:layout_height="87dp"
|
||||
android:layout_marginHorizontal="32dp"
|
||||
android:layout_marginBottom="48dp"
|
||||
android:text="确定"
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btnSave"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:layout_height="87dp"
|
||||
android:layout_marginHorizontal="32dp"
|
||||
android:layout_marginBottom="48dp"
|
||||
android:text="保存"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="Base.Theme.DualScreen" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<style name="Theme.DualScreen" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<!-- Customize your dark theme here. -->
|
||||
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
|
||||
</style>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<!-- <style name="Base.Theme.DualScreen" parent="Theme.Material3.DayNight.NoActionBar">-->
|
||||
<style name="Base.Theme.DualScreen" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<style name="Theme.DualScreen" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your light theme here. -->
|
||||
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
|
||||
</style>
|
||||
|
||||
<style name="Theme.DualScreen" parent="Base.Theme.DualScreen" />
|
||||
|
||||
<style name="text_title_blob">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:textColor">@color/beige_ECE7D0</item>
|
||||
@@ -177,4 +175,9 @@
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">10dp</item>
|
||||
</style>
|
||||
|
||||
<style name="LoadingDialog" parent="Theme.AppCompat.Dialog">
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user