diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 25d81d8..bfc5579 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,9 @@
+
+
+
() {
- private val viewModel by viewModels()
- override fun getViewModel(): BaseViewModel {
- return viewModel
- }
-
- override fun inflateViewBinding(): ActivityCollectedDataBinding {
- return ActivityCollectedDataBinding.inflate(layoutInflater)
- }
-
- private val list: MutableList = mutableListOf()
- private val adapter by lazy {
- CollectedFoodAdapter(list).apply {
- isStateViewEnable = true
- addOnItemChildClickListener(R.id.ivDeleteFood) { _, _, position ->
- deleteGoods(position)
- }
- }
- }
-
- override fun initialize() {
- super.initialize()
- binding.rvFoodList.let {
- it.layoutManager = LinearLayoutManager(this)
- it.adapter = adapter
- }
- binding.ivBack.setOnClickListener { finish() }
- binding.ivGoodsSearch.setOnClickListener {
- val searchName = binding.etInputGoods.text.toString().trim()
- if (searchName.isBlank()) {
- ToastUtils.showToast("请输入物品名称")
- return@setOnClickListener
- }
- getCollectGoods(searchName)
- }
- binding.etInputGoods.let { v ->
- v.addOnActionSearchListener {
- val searchName = binding.etInputGoods.text.toString().trim()
- if (searchName.isBlank()) {
- ToastUtils.showToast("请输入物品名称")
- return@addOnActionSearchListener
- }
- getCollectGoods(searchName)
- }
- v.addTextChangedListener {
- if (it.isNullOrBlank()) {
- getCollectGoods()
- }
- }
- }
- getCollectGoods()
- }
-
-
- private var box: Box? = null
-
- @SuppressLint("NotifyDataSetChanged")
- private fun getCollectGoods(searchName:String?=null) {
- if (box == null) {
- box = ObjectBox.boxStore.boxFor(Food::class)
- }
- list.clear()
- var queryList = box?.all?.distinctBy { it.name }
- if (searchName.isNullOrBlank().not()) {
- queryList = queryList?.filter { it.name?.contains(searchName) == true }
- }
- queryList?.forEach {
- list.add(CollectedFoodBean(foodName = it.name))
- }
- adapter.notifyDataSetChanged()
- if (list.isEmpty()) {
- loadEmptyView()
- }
- binding.root.hideKeyboard()
- }
-
- private var emptyBinding: LayoutEmptySearchBinding? = null
- private fun loadEmptyView() {
- if (emptyBinding == null) {
- emptyBinding = LayoutEmptySearchBinding.inflate(layoutInflater, binding.rvFoodList, false)
- }
- emptyBinding?.root?.let { layout ->
- layout.setOnClickListener { layout.hideKeyboard() }
- adapter.stateView = layout
- }
- }
-
- private fun deleteGoods(position: Int) {
- WarnDialog(
- context = context,
- content = "请确认是否删除菜品:${list[position].foodName}?",
- confirmBlock = {
- Thread {
- runOnUiThread {
- showWaitingDialog("加载中……")
- }
- val name = list[position].foodName
- val filterIdList = box?.all?.filter { it.name == name }?.map { it.id }
- box?.removeByIds(filterIdList)
- runOnUiThread {
- hideWaitingDialog()
- adapter.removeAt(position)
- ToastUtils.showToast("删除成功")
- if (list.isEmpty()) {
- loadEmptyView()
- }
- }
- }.start()
- }).show()
- }
-}
\ No newline at end of file
+//package com.sw.dualscreen.activity
+//
+//import android.annotation.SuppressLint
+//import androidx.activity.viewModels
+//import androidx.core.widget.addTextChangedListener
+//import androidx.recyclerview.widget.LinearLayoutManager
+//import com.sw.dualscreen.R
+//import com.sw.dualscreen.adapter.CollectedFoodAdapter
+//import com.sw.dualscreen.databinding.ActivityCollectedDataBinding
+//import com.sw.dualscreen.databinding.LayoutEmptySearchBinding
+//import com.sw.dualscreen.dialog.WarnDialog
+//import com.sw.dualscreen.ext.addOnActionSearchListener
+//import com.sw.dualscreen.ext.hideKeyboard
+//import com.sw.dualscreen.objbox.CollectedFoodBean
+//import com.sw.dualscreen.objbox.Food
+//import com.sw.dualscreen.objbox.ObjectBox
+//import com.sw.dualscreen.viewmodel.BaseViewModel
+//import com.sw.dualscreen.viewmodel.UserViewModel
+//import com.sw.plate.utils.ToastUtils
+//import io.objectbox.Box
+//import io.objectbox.kotlin.boxFor
+//import kotlin.getValue
+//
+//class CollectedDataActivity : BaseActivity() {
+// private val viewModel by viewModels()
+// override fun getViewModel(): BaseViewModel {
+// return viewModel
+// }
+//
+// override fun inflateViewBinding(): ActivityCollectedDataBinding {
+// return ActivityCollectedDataBinding.inflate(layoutInflater)
+// }
+//
+// private val list: MutableList = mutableListOf()
+// private val adapter by lazy {
+// CollectedFoodAdapter(list).apply {
+// isStateViewEnable = true
+// addOnItemChildClickListener(R.id.ivDeleteFood) { _, _, position ->
+// deleteGoods(position)
+// }
+// }
+// }
+//
+// override fun initialize() {
+// super.initialize()
+// binding.rvFoodList.let {
+// it.layoutManager = LinearLayoutManager(this)
+// it.adapter = adapter
+// }
+// binding.ivBack.setOnClickListener { finish() }
+// binding.ivGoodsSearch.setOnClickListener {
+// val searchName = binding.etInputGoods.text.toString().trim()
+// if (searchName.isBlank()) {
+// ToastUtils.showToast("请输入物品名称")
+// return@setOnClickListener
+// }
+// getCollectGoods(searchName)
+// }
+// binding.etInputGoods.let { v ->
+// v.addOnActionSearchListener {
+// val searchName = binding.etInputGoods.text.toString().trim()
+// if (searchName.isBlank()) {
+// ToastUtils.showToast("请输入物品名称")
+// return@addOnActionSearchListener
+// }
+// getCollectGoods(searchName)
+// }
+// v.addTextChangedListener {
+// if (it.isNullOrBlank()) {
+// getCollectGoods()
+// }
+// }
+// }
+// getCollectGoods()
+// }
+//
+//
+// private var box: Box? = null
+//
+// @SuppressLint("NotifyDataSetChanged")
+// private fun getCollectGoods(searchName:String?=null) {
+// if (box == null) {
+// box = ObjectBox.boxStore.boxFor(Food::class)
+// }
+// list.clear()
+// var queryList = box?.all?.distinctBy { it.name }
+// if (searchName.isNullOrBlank().not()) {
+// queryList = queryList?.filter { it.name?.contains(searchName) == true }
+// }
+// queryList?.forEach {
+// list.add(CollectedFoodBean(foodName = it.name))
+// }
+// adapter.notifyDataSetChanged()
+// if (list.isEmpty()) {
+// loadEmptyView()
+// }
+// binding.root.hideKeyboard()
+// }
+//
+// private var emptyBinding: LayoutEmptySearchBinding? = null
+// private fun loadEmptyView() {
+// if (emptyBinding == null) {
+// emptyBinding = LayoutEmptySearchBinding.inflate(layoutInflater, binding.rvFoodList, false)
+// }
+// emptyBinding?.root?.let { layout ->
+// layout.setOnClickListener { layout.hideKeyboard() }
+// adapter.stateView = layout
+// }
+// }
+//
+// private fun deleteGoods(position: Int) {
+// WarnDialog(
+// context = context,
+// content = "请确认是否删除菜品:${list[position].foodName}?",
+// confirmBlock = {
+// Thread {
+// runOnUiThread {
+// showWaitingDialog("加载中……")
+// }
+// val name = list[position].foodName
+// val filterIdList = box?.all?.filter { it.name == name }?.map { it.id }
+// box?.removeByIds(filterIdList)
+// runOnUiThread {
+// hideWaitingDialog()
+// adapter.removeAt(position)
+// ToastUtils.showToast("删除成功")
+// if (list.isEmpty()) {
+// loadEmptyView()
+// }
+// }
+// }.start()
+// }).show()
+// }
+//}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/CollectedFoodActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/CollectedFoodActivity.kt
new file mode 100644
index 0000000..32687ff
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/CollectedFoodActivity.kt
@@ -0,0 +1,137 @@
+package com.sw.dualscreen.activity
+
+import android.annotation.SuppressLint
+import androidx.activity.viewModels
+import androidx.core.widget.addTextChangedListener
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.sw.dualscreen.R
+import com.sw.dualscreen.adapter.CollectedFoodNewAdapter
+import com.sw.dualscreen.databinding.ActivityCollectedFoodBinding
+import com.sw.dualscreen.databinding.LayoutEmptySearchBinding
+import com.sw.dualscreen.dialog.WarnDialog
+import com.sw.dualscreen.ext.addOnActionSearchListener
+import com.sw.dualscreen.ext.hideKeyboard
+import com.sw.dualscreen.objbox.CollectedFoodBean
+import com.sw.dualscreen.objbox.Food
+import com.sw.dualscreen.objbox.ObjectBox
+import com.sw.dualscreen.viewmodel.BaseViewModel
+import com.sw.dualscreen.viewmodel.UserViewModel
+import com.sw.plate.utils.ToastUtils
+import io.objectbox.Box
+import io.objectbox.kotlin.boxFor
+
+class CollectedFoodActivity : BaseActivity() {
+ private val viewModel by viewModels()
+ override fun getViewModel(): BaseViewModel {
+ return viewModel
+ }
+
+ override fun inflateViewBinding(): ActivityCollectedFoodBinding {
+ return ActivityCollectedFoodBinding.inflate(layoutInflater)
+ }
+
+ private val list: MutableList = mutableListOf()
+ private val adapter by lazy {
+ CollectedFoodNewAdapter(list).apply {
+ isStateViewEnable = true
+ addOnItemChildClickListener(R.id.ivDeleteFood) { _, _, position ->
+ deleteGoods(position)
+ }
+ }
+ }
+
+ override fun initialize() {
+ super.initialize()
+ binding.rvFoodList.let {
+ it.layoutManager = LinearLayoutManager(this)
+ it.adapter = adapter
+ }
+ binding.include.let {
+ it.tvPageTitle.text = "已采集餐品"
+ it.ivPageBack.setOnClickListener { finish() }
+ }
+ binding.ivFoodSearch.setOnClickListener {
+ val searchName = binding.etInputFood.text.toString().trim()
+ if (searchName.isBlank()) {
+ ToastUtils.showToast("请输入物品名称")
+ return@setOnClickListener
+ }
+ getCollectGoods(searchName)
+ }
+ binding.etInputFood.let { v ->
+ v.addOnActionSearchListener {
+ val searchName = binding.etInputFood.text.toString().trim()
+ if (searchName.isBlank()) {
+ ToastUtils.showToast("请输入物品名称")
+ return@addOnActionSearchListener
+ }
+ getCollectGoods(searchName)
+ }
+ v.addTextChangedListener {
+ if (it.isNullOrBlank()) {
+ getCollectGoods()
+ }
+ }
+ }
+ getCollectGoods()
+ }
+
+
+ private var box: Box? = null
+
+ @SuppressLint("NotifyDataSetChanged")
+ private fun getCollectGoods(searchName: String? = null) {
+ if (box == null) {
+ box = ObjectBox.boxStore.boxFor(Food::class)
+ }
+ list.clear()
+ var queryList = box?.all?.distinctBy { it.name }
+ if (searchName.isNullOrBlank().not()) {
+ queryList = queryList?.filter { it.name?.contains(searchName) == true }
+ }
+ queryList?.forEach {
+ list.add(CollectedFoodBean(foodName = it.name))
+ }
+ adapter.notifyDataSetChanged()
+ if (list.isEmpty()) {
+ loadEmptyView()
+ }
+ binding.root.hideKeyboard()
+ }
+
+ private var emptyBinding: LayoutEmptySearchBinding? = null
+ private fun loadEmptyView() {
+ if (emptyBinding == null) {
+ emptyBinding =
+ LayoutEmptySearchBinding.inflate(layoutInflater, binding.rvFoodList, false)
+ }
+ emptyBinding?.root?.let { layout ->
+ layout.setOnClickListener { layout.hideKeyboard() }
+ adapter.stateView = layout
+ }
+ }
+
+ private fun deleteGoods(position: Int) {
+ WarnDialog(
+ context = context,
+ content = "请确认是否删除菜品:${list[position].foodName}?",
+ confirmBlock = {
+ Thread {
+ runOnUiThread {
+ showWaitingDialog("加载中……")
+ }
+ val name = list[position].foodName
+ val filterIdList = box?.all?.filter { it.name == name }?.map { it.id }
+ box?.removeByIds(filterIdList)
+ runOnUiThread {
+ hideWaitingDialog()
+ adapter.removeAt(position)
+ ToastUtils.showToast("删除成功")
+ if (list.isEmpty()) {
+ loadEmptyView()
+ }
+ }
+ }.start()
+ }).show()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/FoodCollectionActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/FoodCollectionActivity.kt
index 32f3b2b..be4bcc0 100644
--- a/app/src/main/java/com/sw/dualscreen/activity/FoodCollectionActivity.kt
+++ b/app/src/main/java/com/sw/dualscreen/activity/FoodCollectionActivity.kt
@@ -1,370 +1,370 @@
-package com.sw.dualscreen.activity
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.Typeface
-import android.net.Uri
-import android.view.View
-import android.view.inputmethod.EditorInfo
-import android.view.inputmethod.InputMethodManager
-import android.widget.Toast
-import androidx.activity.viewModels
-import androidx.camera.view.PreviewView
-import androidx.core.net.toUri
-import androidx.core.view.updateLayoutParams
-import androidx.lifecycle.lifecycleScope
-import androidx.recyclerview.widget.GridLayoutManager
-import com.example.utils.FloatBase64Utils
-import com.sw.dualscreen.R
-import com.sw.dualscreen.adapter.FoodCollectionAdapter
-import com.sw.dualscreen.adapter.GenericItemAdapter
-import com.sw.dualscreen.adapter.GridSpacingItemDecoration
-import com.sw.dualscreen.adapter.dpToPx
-import com.sw.dualscreen.databinding.ActivityFoodCollectionBinding
-import com.sw.dualscreen.databinding.ItemSearchFoodInfoBinding
-import com.sw.dualscreen.databinding.LayoutCameraPreviewBinding
-import com.sw.dualscreen.ext.clickWithDebounce
-import com.sw.dualscreen.ext.dp
-import com.sw.dualscreen.model.response.FoodInfo
-import com.sw.dualscreen.objbox.Food
-import com.sw.dualscreen.objbox.FoodCollectionBean
-import com.sw.dualscreen.objbox.FoodModule
-import com.sw.dualscreen.objbox.ObjectBox
-import com.sw.dualscreen.utils.BitmapCropper
-import com.sw.dualscreen.utils.BitmapSaver
-import com.sw.dualscreen.utils.CameraHelper
-import com.sw.dualscreen.utils.CameraUtils
-import com.sw.dualscreen.utils.Debouncer
-import com.sw.dualscreen.utils.ImageUtil
-import com.sw.dualscreen.viewmodel.BaseViewModel
-import com.sw.dualscreen.viewmodel.UserViewModel
-import com.sw.plate.utils.ToastUtils
-import io.objectbox.Box
-import io.objectbox.kotlin.boxFor
-import kotlinx.coroutines.launch
-import org.pytorch.IValue
-import org.pytorch.Module
-import org.pytorch.torchvision.TensorImageUtils
-import timber.log.Timber
-import kotlin.math.max
-
-class FoodCollectionActivity : BaseActivity() {
- companion object {
- val MAX_COUNT = 100
- }
- private val viewModel by viewModels()
- private var selectedFoodId: String? = ""
- private var selectedFoodName: String? = ""
-
- private var box: Box? = null
- private val foodCollectionList: MutableList = mutableListOf()
-
-// private lateinit var cameraHelper: CameraHelper
-
- private lateinit var foodAdapter: GenericItemAdapter
- private val foodList = mutableListOf() // 适配器内部维护的数据列表
- private val debouncer = Debouncer(2000)
- private lateinit var previewView: PreviewView
-
- private val cameraUtils: CameraUtils by lazy {
- CameraUtils(this)
- }
-
- private val collectionAdapter: FoodCollectionAdapter by lazy {
- FoodCollectionAdapter(foodCollectionList).apply {
-// setOnItemClickListener { _, _, position ->
-// if (list[position].isShowCamera) {
-//// takePhoto()
-// cameraHelper.openCamera()
+//package com.sw.dualscreen.activity
+//
+//import android.annotation.SuppressLint
+//import android.content.Context
+//import android.content.Intent
+//import android.graphics.Bitmap
+//import android.graphics.Typeface
+//import android.net.Uri
+//import android.view.View
+//import android.view.inputmethod.EditorInfo
+//import android.view.inputmethod.InputMethodManager
+//import android.widget.Toast
+//import androidx.activity.viewModels
+//import androidx.camera.view.PreviewView
+//import androidx.core.net.toUri
+//import androidx.core.view.updateLayoutParams
+//import androidx.lifecycle.lifecycleScope
+//import androidx.recyclerview.widget.GridLayoutManager
+//import com.example.utils.FloatBase64Utils
+//import com.sw.dualscreen.R
+//import com.sw.dualscreen.adapter.FoodCollectionAdapter
+//import com.sw.dualscreen.adapter.GenericItemAdapter
+//import com.sw.dualscreen.adapter.GridSpacingItemDecoration
+//import com.sw.dualscreen.adapter.dpToPx
+//import com.sw.dualscreen.databinding.ActivityFoodCollectionBinding
+//import com.sw.dualscreen.databinding.ItemSearchFoodInfoBinding
+//import com.sw.dualscreen.databinding.LayoutCameraPreviewBinding
+//import com.sw.dualscreen.ext.clickWithDebounce
+//import com.sw.dualscreen.ext.dp
+//import com.sw.dualscreen.model.response.FoodInfo
+//import com.sw.dualscreen.objbox.Food
+//import com.sw.dualscreen.objbox.FoodCollectionBean
+//import com.sw.dualscreen.objbox.FoodModule
+//import com.sw.dualscreen.objbox.ObjectBox
+//import com.sw.dualscreen.utils.BitmapCropper
+//import com.sw.dualscreen.utils.BitmapSaver
+//import com.sw.dualscreen.utils.CameraHelper
+//import com.sw.dualscreen.utils.CameraUtils
+//import com.sw.dualscreen.utils.Debouncer
+//import com.sw.dualscreen.utils.ImageUtil
+//import com.sw.dualscreen.viewmodel.BaseViewModel
+//import com.sw.dualscreen.viewmodel.UserViewModel
+//import com.sw.plate.utils.ToastUtils
+//import io.objectbox.Box
+//import io.objectbox.kotlin.boxFor
+//import kotlinx.coroutines.launch
+//import org.pytorch.IValue
+//import org.pytorch.Module
+//import org.pytorch.torchvision.TensorImageUtils
+//import timber.log.Timber
+//import kotlin.math.max
+//
+//class FoodCollectionActivity : BaseActivity() {
+// companion object {
+// val MAX_COUNT = 100
+// }
+// private val viewModel by viewModels()
+// private var selectedFoodId: String? = ""
+// private var selectedFoodName: String? = ""
+//
+// private var box: Box? = null
+// private val foodCollectionList: MutableList = mutableListOf()
+//
+//// private lateinit var cameraHelper: CameraHelper
+//
+// private lateinit var foodAdapter: GenericItemAdapter
+// private val foodList = mutableListOf() // 适配器内部维护的数据列表
+// private val debouncer = Debouncer(2000)
+// private lateinit var previewView: PreviewView
+//
+// private val cameraUtils: CameraUtils by lazy {
+// CameraUtils(this)
+// }
+//
+// private val collectionAdapter: FoodCollectionAdapter by lazy {
+// FoodCollectionAdapter(foodCollectionList).apply {
+//// setOnItemClickListener { _, _, position ->
+//// if (list[position].isShowCamera) {
+////// takePhoto()
+//// cameraHelper.openCamera()
+//// }
+//// }
+// addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
+//// list.removeAt(position)
+//// collectionAdapter.notifyItemRemoved(position)
+//// collectionAdapter.notifyItemRangeChanged(position, list.size)
+// foodCollectionList[position].let {
+// it.bitmap = null
+// it.isShowCamera = true
+// it.isFinish = false
+// }
+// notifyItemChanged(position)
+// }
+// }
+// }
+//
+// override fun getViewModel(): BaseViewModel {
+// return viewModel
+// }
+//
+// override fun inflateViewBinding(): ActivityFoodCollectionBinding {
+// return ActivityFoodCollectionBinding.inflate(layoutInflater)
+// }
+//
+// private val cameraCallback: (Uri) -> Unit = { uri ->
+// val index = foodCollectionList.indexOfFirst { it.bitmap == null }
+// if (index == -1) {
+// ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
+// rerurn@ cameraCallback
+// }
+// ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
+//// val cropBitmap = BitmapCropper.cropCenter(
+//// original = bitmap,
+//// targetWidth = 1300, targetHeight = 900,
+//// //offsetX = 30, offsetY = 100
+//// )
+// val file = BitmapSaver.saveToAppFilesDir(
+// bitmap, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
+// )
+// Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
+//
+// foodCollectionList[index].let {
+// it.bitmap = bitmap
+// it.isShowCamera = false
+// it.imageUri = file?.toUri()
+// }
+// collectionAdapter.notifyItemChanged(index)
+// }
+// }
+//
+// @SuppressLint("NotifyDataSetChanged")
+// private fun takePhoto() {
+// val count = foodCollectionList.count { it.bitmap != null }
+// if (count >= MAX_COUNT) {
+// ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
+// return
+// }
+// cameraUtils.takePhoto(cameraCallback)
+// }
+//
+// override fun initialize() {
+// cameraUtils.initCamera()
+// val previewBinding =
+// LayoutCameraPreviewBinding.inflate(layoutInflater, binding.flCameraPreview)
+// previewView = previewBinding.previewView.also {
+// it.updateLayoutParams {
+// width = 180.dp
+// height = 180.dp
+// }
+// }
+// cameraUtils.setPreviewController(previewView)
+// // 初始化 CameraHelper
+//// cameraHelper = CameraHelper(
+//// context = this,
+//// caller = this,
+//// authority = "${packageName}.fileprovider"
+//// ) { uri, path ->
+//// //if (foodCollectionList.size < 6) {
+//// // val insertIndex = if (foodCollectionList.isEmpty()) 0 else foodCollectionList.size - 1
+//// // foodCollectionList.add(insertIndex, FoodCollectionBean(imageUri = uri))
+//// //} else {
+//// // foodCollectionList[foodCollectionList.size - 1] = FoodCollectionBean(imageUri = uri)
+//// //}
+//// //collectionAdapter.notifyDataSetChanged()
+//// cameraCallback(uri)
+//// }
+//
+// binding.ivBack.setOnClickListener {
+// val intent = Intent(this, MainActivity::class.java)
+// startActivity(intent)
+// finish()
+// }
+// repeat(MAX_COUNT) {
+// foodCollectionList.add(FoodCollectionBean(isShowCamera = true))
+// }
+// binding.rvFoodCollection.let {
+// it.layoutManager = GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
+// it.adapter = collectionAdapter
+// }
+//
+// binding.btnFoodSearch.setOnClickListener {
+// searchInfo()
+// }
+//
+// binding.btnSave.setOnClickListener {
+// if (selectedFoodName.isNullOrBlank()) {
+// Toast.makeText(this, "请选择菜品名称", Toast.LENGTH_SHORT).show()
+// return@setOnClickListener
+// }
+// if (foodCollectionList.size <= 1) {
+// Toast.makeText(this, "请拍摄菜品照片", Toast.LENGTH_SHORT).show()
+// return@setOnClickListener
+// }
+// vectorThread()
+// }
+//
+// binding.editFoodName.setOnEditorActionListener { v, actionId, event ->
+// if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+// searchInfo()
+// val imm =
+// v.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+// imm.hideSoftInputFromWindow(v.windowToken, 0)
+// true
+// } else {
+// false
+// }
+// }
+//
+// binding.btnCollectedGoods.setOnClickListener {
+// startActivity(Intent(this, CollectedDataActivity::class.java))
+// }
+// binding.btnTakePhoto.clickWithDebounce {
+// binding.btnTakePhoto.text = "拍照"
+// val count = foodCollectionList.count { it.bitmap != null }
+// if (count >= MAX_COUNT) {
+// ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
+// return@clickWithDebounce
+// }
+//// cameraHelper.openCamera()
+// takePhoto()
+// }
+// binding.btnClearData.setOnClickListener { clearData() }
+// foodAdapter = createAdapter()
+// binding.recyclerview.layoutManager = GridLayoutManager(context, 2)
+// // 添加间距装饰(12dp)
+// binding.recyclerview.addItemDecoration(
+// GridSpacingItemDecoration(
+// spanCount = 2,
+// spacing = dpToPx(30),
+// includeEdge = false // 包含边缘间距
+// )
+// )
+// binding.recyclerview.adapter = foodAdapter
+// }
+//
+// private fun vectorThread() {
+// //Loading.show(this)
+// showWaitingDialog("加载中……")
+// Thread {
+// foodCollectionList
+// .filter { it.bitmap != null }
+// .forEachIndexed { index, it ->
+// image2VectorTask(it, index)
+// }
+// runOnUiThread {
+// window.decorView.postDelayed({
+// //Loading.dismiss()
+// hideWaitingDialog()
+// }, 1000)
+// }
+// }.start()
+// }
+//
+// private fun initBox() {
+// if (box == null) {
+// box = ObjectBox.boxStore.boxFor(Food::class)
+// }
+// }
+//
+// private fun image2VectorTask(item: FoodCollectionBean, position: Int) {
+// initBox()
+// val imageVector = FoodModule.bitmap2FloatArray(item.bitmap!!)
+//
+// val base64Str = FloatBase64Utils.floatArrayToBase64(imageVector)
+// Timber.tag("mzf1").e(base64Str)
+//// viewModel.postImageData(
+//// context,
+//// foodId = selectedFoodId.toString(),
+//// foodName = selectedFoodName.toString(),
+//// foodVector = base64Str,
+//// uri = item.imageUri!!
+//// )
+// box?.put(Food(name = checkedItem!!.foodName, foodIdx = 0, foodVector = imageVector))
+// foodCollectionList[position].let {
+// it.imageVector = imageVector
+// it.isFinish = true
+// }
+//
+// runOnUiThread {
+// collectionAdapter.notifyItemChanged(position)
+// }
+// }
+//
+//
+// private fun searchInfo() {
+// debouncer.debounce {
+// viewModel.searchByFoodName(binding.editFoodName.text.toString())
+// }
+// }
+//
+// override fun registerDataChange() {
+// super.registerDataChange()
+// lifecycleScope.launch {
+// viewModel.searchFoodInfoList.collect {
+//// foodList.clear()
+//// foodList.addAll(it)
+// foodAdapter.updateData(it)
+// }
+// }
+// }
+//
+//
+// private var checkedItem: FoodInfo? = null
+// private fun createAdapter(): GenericItemAdapter {
+// return GenericItemAdapter(
+// items = emptyList(),
+// bindingInflater = ItemSearchFoodInfoBinding::inflate,
+// bindCallback = { item, position ->
+// this.tvName.text = item.foodName
+// if (item.id != checkedItem?.id) {
+// this.tvName.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
+// this.tvName.setTextColor(resources.getColor(R.color.search_normal))
+// this.llRoot.setBackgroundResource(R.drawable.grid_search_item_normal)
+// } else {
+// this.tvName.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
+// this.tvName.setTextColor(resources.getColor(R.color.search_checked))
+// this.llRoot.setBackgroundResource(R.drawable.grid_search_item_checked)
+// }
+//
+// this.llRoot.setOnClickListener {
+// Timber.d("itemClick ${item.foodName}, position = $position")
+// checkedItem = item
+//// viewModel.updateCurrentItem(item)
+//// itemClickCallback(item)
+// selectedFoodName = item.foodName
+// selectedFoodId = item.id
+//
+// foodAdapter.notifyDataSetChanged()
// }
// }
- addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
-// list.removeAt(position)
-// collectionAdapter.notifyItemRemoved(position)
-// collectionAdapter.notifyItemRangeChanged(position, list.size)
- foodCollectionList[position].let {
- it.bitmap = null
- it.isShowCamera = true
- it.isFinish = false
- }
- notifyItemChanged(position)
- }
- }
- }
-
- override fun getViewModel(): BaseViewModel {
- return viewModel
- }
-
- override fun inflateViewBinding(): ActivityFoodCollectionBinding {
- return ActivityFoodCollectionBinding.inflate(layoutInflater)
- }
-
- private val cameraCallback: (Uri) -> Unit = { uri ->
- val index = foodCollectionList.indexOfFirst { it.bitmap == null }
- if (index == -1) {
- ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
- rerurn@ cameraCallback
- }
- ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
-// val cropBitmap = BitmapCropper.cropCenter(
-// original = bitmap,
-// targetWidth = 1300, targetHeight = 900,
-// //offsetX = 30, offsetY = 100
-// )
- val file = BitmapSaver.saveToAppFilesDir(
- bitmap, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
- )
- Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
-
- foodCollectionList[index].let {
- it.bitmap = bitmap
- it.isShowCamera = false
- it.imageUri = file?.toUri()
- }
- collectionAdapter.notifyItemChanged(index)
- }
- }
-
- @SuppressLint("NotifyDataSetChanged")
- private fun takePhoto() {
- val count = foodCollectionList.count { it.bitmap != null }
- if (count >= MAX_COUNT) {
- ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
- return
- }
- cameraUtils.takePhoto(cameraCallback)
- }
-
- override fun initialize() {
- cameraUtils.initCamera()
- val previewBinding =
- LayoutCameraPreviewBinding.inflate(layoutInflater, binding.flCameraPreview)
- previewView = previewBinding.previewView.also {
- it.updateLayoutParams {
- width = 180.dp
- height = 180.dp
- }
- }
- cameraUtils.setPreviewController(previewView)
- // 初始化 CameraHelper
-// cameraHelper = CameraHelper(
-// context = this,
-// caller = this,
-// authority = "${packageName}.fileprovider"
-// ) { uri, path ->
-// //if (foodCollectionList.size < 6) {
-// // val insertIndex = if (foodCollectionList.isEmpty()) 0 else foodCollectionList.size - 1
-// // foodCollectionList.add(insertIndex, FoodCollectionBean(imageUri = uri))
-// //} else {
-// // foodCollectionList[foodCollectionList.size - 1] = FoodCollectionBean(imageUri = uri)
-// //}
-// //collectionAdapter.notifyDataSetChanged()
-// cameraCallback(uri)
-// }
-
- binding.ivBack.setOnClickListener {
- val intent = Intent(this, MainActivity::class.java)
- startActivity(intent)
- finish()
- }
- repeat(MAX_COUNT) {
- foodCollectionList.add(FoodCollectionBean(isShowCamera = true))
- }
- binding.rvFoodCollection.let {
- it.layoutManager = GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
- it.adapter = collectionAdapter
- }
-
- binding.btnFoodSearch.setOnClickListener {
- searchInfo()
- }
-
- binding.btnSave.setOnClickListener {
- if (selectedFoodName.isNullOrBlank()) {
- Toast.makeText(this, "请选择菜品名称", Toast.LENGTH_SHORT).show()
- return@setOnClickListener
- }
- if (foodCollectionList.size <= 1) {
- Toast.makeText(this, "请拍摄菜品照片", Toast.LENGTH_SHORT).show()
- return@setOnClickListener
- }
- vectorThread()
- }
-
- binding.editFoodName.setOnEditorActionListener { v, actionId, event ->
- if (actionId == EditorInfo.IME_ACTION_SEARCH) {
- searchInfo()
- val imm =
- v.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
- imm.hideSoftInputFromWindow(v.windowToken, 0)
- true
- } else {
- false
- }
- }
-
- binding.btnCollectedGoods.setOnClickListener {
- startActivity(Intent(this, CollectedDataActivity::class.java))
- }
- binding.btnTakePhoto.clickWithDebounce {
- binding.btnTakePhoto.text = "拍照"
- val count = foodCollectionList.count { it.bitmap != null }
- if (count >= MAX_COUNT) {
- ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
- return@clickWithDebounce
- }
-// cameraHelper.openCamera()
- takePhoto()
- }
- binding.btnClearData.setOnClickListener { clearData() }
- foodAdapter = createAdapter()
- binding.recyclerview.layoutManager = GridLayoutManager(context, 2)
- // 添加间距装饰(12dp)
- binding.recyclerview.addItemDecoration(
- GridSpacingItemDecoration(
- spanCount = 2,
- spacing = dpToPx(30),
- includeEdge = false // 包含边缘间距
- )
- )
- binding.recyclerview.adapter = foodAdapter
- }
-
- private fun vectorThread() {
- //Loading.show(this)
- showWaitingDialog("加载中……")
- Thread {
- foodCollectionList
- .filter { it.bitmap != null }
- .forEachIndexed { index, it ->
- image2VectorTask(it, index)
- }
- runOnUiThread {
- window.decorView.postDelayed({
- //Loading.dismiss()
- hideWaitingDialog()
- }, 1000)
- }
- }.start()
- }
-
- private fun initBox() {
- if (box == null) {
- box = ObjectBox.boxStore.boxFor(Food::class)
- }
- }
-
- private fun image2VectorTask(item: FoodCollectionBean, position: Int) {
- initBox()
- val imageVector = FoodModule.bitmap2FloatArray(item.bitmap!!)
-
- val base64Str = FloatBase64Utils.floatArrayToBase64(imageVector)
- Timber.tag("mzf1").e(base64Str)
-// viewModel.postImageData(
-// context,
-// foodId = selectedFoodId.toString(),
-// foodName = selectedFoodName.toString(),
-// foodVector = base64Str,
-// uri = item.imageUri!!
// )
- box?.put(Food(name = checkedItem!!.foodName, foodIdx = 0, foodVector = imageVector))
- foodCollectionList[position].let {
- it.imageVector = imageVector
- it.isFinish = true
- }
-
- runOnUiThread {
- collectionAdapter.notifyItemChanged(position)
- }
- }
-
-
- private fun searchInfo() {
- debouncer.debounce {
- viewModel.searchByFoodName(binding.editFoodName.text.toString())
- }
- }
-
- override fun registerDataChange() {
- super.registerDataChange()
- lifecycleScope.launch {
- viewModel.searchFoodInfoList.collect {
-// foodList.clear()
-// foodList.addAll(it)
- foodAdapter.updateData(it)
- }
- }
- }
-
-
- private var checkedItem: FoodInfo? = null
- private fun createAdapter(): GenericItemAdapter {
- return GenericItemAdapter(
- items = emptyList(),
- bindingInflater = ItemSearchFoodInfoBinding::inflate,
- bindCallback = { item, position ->
- this.tvName.text = item.foodName
- if (item.id != checkedItem?.id) {
- this.tvName.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
- this.tvName.setTextColor(resources.getColor(R.color.search_normal))
- this.llRoot.setBackgroundResource(R.drawable.grid_search_item_normal)
- } else {
- this.tvName.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
- this.tvName.setTextColor(resources.getColor(R.color.search_checked))
- this.llRoot.setBackgroundResource(R.drawable.grid_search_item_checked)
- }
-
- this.llRoot.setOnClickListener {
- Timber.d("itemClick ${item.foodName}, position = $position")
- checkedItem = item
-// viewModel.updateCurrentItem(item)
-// itemClickCallback(item)
- selectedFoodName = item.foodName
- selectedFoodId = item.id
-
- foodAdapter.notifyDataSetChanged()
- }
- }
- )
- }
-
- private var clickIndex = -1
-
- @SuppressLint("NotifyDataSetChanged")
- private fun clearData() {
- foodCollectionList.forEach {
- it.bitmap = null
- it.isShowCamera = true
- it.isFinish = false
- }
- collectionAdapter.notifyDataSetChanged()
-
- clickIndex = -1
- binding.editFoodName.setText("")
-// foodList.clear()
-// foodAdapter.updateData(mutableListOf())
-// foodAdapter.notifyDataSetChanged()
- //loadEmptyView()
- }
-
- override fun onResume() {
- super.onResume()
- cameraUtils.bind()
- binding.llCameraFlag.run {
- visibility = View.VISIBLE
- postDelayed({
- visibility = View.GONE
- }, 3000)
- }
- }
-
- override fun onPause() {
- super.onPause()
- cameraUtils.unbind()
- binding.llCameraFlag.visibility = View.VISIBLE
- }
-
-}
\ No newline at end of file
+// }
+//
+// private var clickIndex = -1
+//
+// @SuppressLint("NotifyDataSetChanged")
+// private fun clearData() {
+// foodCollectionList.forEach {
+// it.bitmap = null
+// it.isShowCamera = true
+// it.isFinish = false
+// }
+// collectionAdapter.notifyDataSetChanged()
+//
+// clickIndex = -1
+// binding.editFoodName.setText("")
+//// foodList.clear()
+//// foodAdapter.updateData(mutableListOf())
+//// foodAdapter.notifyDataSetChanged()
+// //loadEmptyView()
+// }
+//
+// override fun onResume() {
+// super.onResume()
+// cameraUtils.bind()
+// binding.llCameraFlag.run {
+// visibility = View.VISIBLE
+// postDelayed({
+// visibility = View.GONE
+// }, 3000)
+// }
+// }
+//
+// override fun onPause() {
+// super.onPause()
+// cameraUtils.unbind()
+// binding.llCameraFlag.visibility = View.VISIBLE
+// }
+//
+//}
\ No newline at end of file
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 454f28b..ed9cae1 100644
--- a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt
+++ b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt
@@ -1,5 +1,6 @@
package com.sw.dualscreen.activity
+import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.Outline
@@ -28,11 +29,13 @@ import com.sw.dualscreen.GlobalKey
import com.sw.dualscreen.R
import com.sw.dualscreen.adapter.GenericItemAdapter
import com.sw.dualscreen.adapter.GridSpacingItemDecoration
+import com.sw.dualscreen.adapter.SearchFoodAdapter
import com.sw.dualscreen.adapter.dpToPx
import com.sw.dualscreen.databinding.ActivityMainBinding
import com.sw.dualscreen.databinding.ItemFoodInfoBinding
import com.sw.dualscreen.ext.dp
import com.sw.dualscreen.ext.format2String
+import com.sw.dualscreen.ext.visible
import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.objbox.FoodModule
import com.sw.dualscreen.objbox.FoodModule.IdNameScore
@@ -55,6 +58,10 @@ import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
import kotlinx.coroutines.launch
import timber.log.Timber
import java.io.File
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
+import java.util.Locale
import java.util.concurrent.Executors
import kotlin.math.roundToInt
@@ -67,7 +74,23 @@ class MainActivity : BaseActivity() {
private var isAnalyzing = true // 控制是否进行图像分析
private var presentation: SecondaryScreenPresentation? = null
private val executor = Executors.newSingleThreadExecutor()
- private lateinit var adapter: GenericItemAdapter
+ private val searchFoodList = mutableListOf()
+ private val adapter by lazy {
+ SearchFoodAdapter(searchFoodList).apply {
+ setOnItemClickListener { adapter, view, position ->
+ searchFoodList.forEachIndexed { index, info ->
+ searchFoodList[index].isChecked = index == position
+ }
+ val item = searchFoodList[position]
+ Timber.d("itemClick ${item.foodName}, position = $position")
+ item.photoUri = null
+ checkedItem = item
+ notifyDataSetChanged()
+ // TODO 暂时注释---------------
+ //updateCurrentFood(item)
+ }
+ }
+ }
private var checkedItem: FoodInfo? = null
private var imageAnalysis: ImageAnalysis? = null
private var cameraProviderFuture: ListenableFuture? = null
@@ -102,11 +125,16 @@ class MainActivity : BaseActivity() {
private fun initView() {
viewModel.activeEngine()
- binding.foodDisplayLayout.setOnClickListener {
- val intent = Intent(this, FoodCollectionActivity::class.java)
- startActivity(intent)
+ updateDateTime()
+ binding.ivSetting.setOnClickListener {
+ startActivity(Intent(this, SettingActivity::class.java))
finish()
}
+ //binding.foodDisplayLayout.setOnClickListener {
+ // val intent = Intent(this, FoodCollectionActivity::class.java)
+ // startActivity(intent)
+ // finish()
+ //}
binding.previewView.outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setRoundRect(0, 0, view.width, view.height, 12f.dp)
@@ -121,49 +149,57 @@ class MainActivity : BaseActivity() {
bottomSheetDialog!!.show(supportFragmentManager, "CustomBottomSheetDialog")
}
- val spinnerAdapter = ArrayAdapter(
- this,
- R.layout.item_for_custom_spinner,
- arrayOf("即放即取", "余量取餐")
- )
- binding.spinner.adapter = spinnerAdapter
+ //val spinnerAdapter = ArrayAdapter(
+ // this,
+ // R.layout.item_for_custom_spinner,
+ // arrayOf("即放即取", "余量取餐")
+ //)
+ //binding.spinner.adapter = spinnerAdapter
val mode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0)
- binding.spinner.setSelection(mode ?: 0)
+ //binding.spinner.setSelection(mode ?: 0)
presentation?.updateMealPickupMode(mode ?: 0)
- binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
- override fun onItemSelected(
- parent: AdapterView<*>?,
- view: View?,
- position: Int,
- id: Long
- ) {
- SPUtil.getInstance().put(GlobalKey.KEY_PICKUP_MODE, position)
- updateCurrentFood(null)
- isRecognitionFood = true
- presentation?.updateMealPickupMode(position)
-
- SensorScaleUtils.zero()
- }
-
- override fun onNothingSelected(parent: AdapterView<*>?) {}
+ //binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
+ // override fun onItemSelected(
+ // parent: AdapterView<*>?,
+ // view: View?,
+ // position: Int,
+ // id: Long
+ // ) {
+ // SPUtil.getInstance().put(GlobalKey.KEY_PICKUP_MODE, position)
+ // updateCurrentFood(null)
+ // isRecognitionFood = true
+ // presentation?.updateMealPickupMode(position)
+//
+ // SensorScaleUtils.zero()
+ // }
+//
+ // override fun onNothingSelected(parent: AdapterView<*>?) {}
+ //}
+ //adapter = createAdapter()
+ binding.recyclerview.let {
+ it.layoutManager = GridLayoutManager(this, 2)
+ it.adapter = adapter
}
- adapter = createAdapter()
- binding.recyclerview.layoutManager = GridLayoutManager(this, 2)
// 添加间距装饰(12dp)
- binding.recyclerview.addItemDecoration(
- GridSpacingItemDecoration(
- spanCount = 2,
- spacing = dpToPx(30),
- includeEdge = false // 包含边缘间距
- )
- )
- binding.recyclerview.adapter = adapter
+ //binding.recyclerview.addItemDecoration(
+ // GridSpacingItemDecoration(
+ // spanCount = 2,
+ // spacing = dpToPx(30),
+ // includeEdge = false // 包含边缘间距
+ // )
+ //)
+ //binding.recyclerview.adapter = adapter
binding.tvFoodName.setOnClickListener {
SensorScaleUtils.zero()
}
binding.tvRescan.setOnClickListener {
debouncer.debounce { recognizeFood() }
}
+ binding.btnPay.setOnClickListener {
+ startActivity(Intent(this, PayActivity::class.java).apply {
+ putExtra(PayActivity.FOOD_INFO, checkedItem)
+ })
+ }
}
fun updateCurrentFood(foodInfo: FoodInfo?) {
@@ -204,7 +240,23 @@ class MainActivity : BaseActivity() {
// }
lifecycleScope.launch {
viewModel.identifiedFoodInfoList.collect { list ->
- adapter.updateData(list)
+ //adapter.updateData(list)
+ searchFoodList.clear()
+ searchFoodList.addAll(list)
+ adapter.notifyDataSetChanged()
+
+ //TODO 暂时写死数据测试---------------------------
+ binding.flPay.visible()
+ binding.recyclerview.visible()
+ searchFoodList.clear()
+ searchFoodList.add(FoodInfo(foodName = "岐山臊子面"))
+ searchFoodList.add(FoodInfo(foodName = "肉末干拌面"))
+ searchFoodList.add(FoodInfo(foodName = "雪菜肉丝面"))
+ searchFoodList.add(FoodInfo(foodName = "康帅博方便面"))
+ searchFoodList.add(FoodInfo(foodName = "担担面"))
+ searchFoodList.add(FoodInfo(foodName = "四合一干拌面"))
+ adapter.notifyDataSetChanged()
+
if (list.isNotEmpty()) {
checkedItem = list[0]
checkedItem!!.photoUri = lastPhotoUri
@@ -213,7 +265,8 @@ class MainActivity : BaseActivity() {
}
}
}
- SensorScaleUtils.startScale { weight ->
+
+ SensorScaleUtils.addWeightListener { weight ->
Timber.d("registerDataChange weight = $weight")
presentation?.updateWeight(weight)
@@ -281,6 +334,7 @@ class MainActivity : BaseActivity() {
}
}
+ @SuppressLint("NotifyDataSetChanged")
private fun updateFoodInfo(list: List, scoreList: List) {
Timber.d("registerDataChange识别后查询接口数据:${GsonUtils.toJson(list)}")
list.forEach { foodInfo ->
@@ -288,7 +342,10 @@ class MainActivity : BaseActivity() {
val score = scoreItem?.score ?: 0.0
foodInfo.score = ((1 - score) * 10000).roundToInt()
}
- adapter.updateData(list)
+ searchFoodList.clear()
+ searchFoodList.addAll(list)
+ adapter.notifyDataSetChanged()
+ //adapter.updateData(list)
if (list.isNotEmpty()) {
checkedItem = list[0]
checkedItem!!.photoUri = lastPhotoUri
@@ -298,33 +355,33 @@ class MainActivity : BaseActivity() {
}
}
- private fun createAdapter(): GenericItemAdapter {
- return GenericItemAdapter(
- items = emptyList(),
- bindingInflater = ItemFoodInfoBinding::inflate,
- bindCallback = { item, position ->
- val score = (item.score / 100.0).format2String(2)
- this.tvName.text = "${item.foodName}\n${score}%"
- if (item.id != checkedItem?.id) {
- this.tvName.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
- this.tvName.setTextColor(resources.getColor(R.color.identify_normal))
- this.llRoot.setBackgroundResource(R.drawable.grid_item_normal)
- } else {
- this.tvName.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
- this.tvName.setTextColor(resources.getColor(R.color.identify_checked))
- this.llRoot.setBackgroundResource(R.drawable.grid_item_checked)
- }
-//
- this.llRoot.setOnClickListener {
- Timber.d("itemClick ${item.foodName}, position = $position")
- item.photoUri = null
- checkedItem = item
- adapter.notifyDataSetChanged()
- updateCurrentFood(item)
- }
- }
- )
- }
+// private fun createAdapter(): GenericItemAdapter {
+// return GenericItemAdapter(
+// items = emptyList(),
+// bindingInflater = ItemFoodInfoBinding::inflate,
+// bindCallback = { item, position ->
+// val score = (item.score / 100.0).format2String(2)
+// this.tvName.text = "${item.foodName}\n${score}%"
+// if (item.id != checkedItem?.id) {
+// this.tvName.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
+// this.tvName.setTextColor(resources.getColor(R.color.identify_normal))
+// this.llRoot.setBackgroundResource(R.drawable.grid_item_normal)
+// } else {
+// this.tvName.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
+// this.tvName.setTextColor(resources.getColor(R.color.identify_checked))
+// this.llRoot.setBackgroundResource(R.drawable.grid_item_checked)
+// }
+////
+// this.llRoot.setOnClickListener {
+// Timber.d("itemClick ${item.foodName}, position = $position")
+// item.photoUri = null
+// checkedItem = item
+// adapter.notifyDataSetChanged()
+// updateCurrentFood(item)
+// }
+// }
+// )
+// }
private fun setupCamera() {
Timber.d("setupCamera")
@@ -496,15 +553,24 @@ class MainActivity : BaseActivity() {
}
}
+ @SuppressLint("NotifyDataSetChanged")
fun clearFoodList() {
- adapter.updateData(listOf())
+ //adapter.updateData(listOf())
+ searchFoodList.clear()
adapter.notifyDataSetChanged()
}
override fun onDestroy() {
- SensorScaleUtils.closeScale()
+ //SensorScaleUtils.closeScale()
presentation?.dismiss()
super.onDestroy()
shutdownCamera()
}
+
+ private fun updateDateTime() {
+ val formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA)
+ val dateTime = formatter.format(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
+ binding.tvTitleTime.text = dateTime
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/PayActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/PayActivity.kt
new file mode 100644
index 0000000..ed19bae
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/PayActivity.kt
@@ -0,0 +1,128 @@
+package com.sw.dualscreen.activity
+
+import android.view.View
+import androidx.activity.viewModels
+import androidx.fragment.app.Fragment
+import com.sw.dualscreen.R
+import com.sw.dualscreen.activity.fragment.CashPayFragment
+import com.sw.dualscreen.activity.fragment.FacePayFragment
+import com.sw.dualscreen.activity.fragment.NumberPayFragment
+import com.sw.dualscreen.activity.fragment.PayResultFragment
+import com.sw.dualscreen.activity.fragment.QrCodePayFragment
+import com.sw.dualscreen.databinding.ActivityPayBinding
+import com.sw.dualscreen.model.response.FoodInfo
+import com.sw.dualscreen.viewmodel.BaseViewModel
+import com.sw.dualscreen.viewmodel.UserViewModel
+
+class PayActivity : BaseActivity() {
+
+ companion object {
+
+ const val FOOD_INFO = "foodInfo"
+ const val TAG_PAY_QR_CODE = "tagPayQrCode"
+ const val TAG_PAY_CASH = "tagPayCash"
+ const val TAG_PAY_NUMBER = "tagPayNumber"
+ const val TAG_PAY_FACE = "tagPayFace"
+ const val TAG_PAY_RESULT = "tagPayResult"
+ }
+
+ private val viewModel by viewModels()
+
+ override fun getViewModel(): BaseViewModel {
+ return viewModel
+ }
+
+ override fun inflateViewBinding(): ActivityPayBinding {
+ return ActivityPayBinding.inflate(layoutInflater)
+ }
+
+ var foodInfo: FoodInfo? = null
+
+ private var qrCodePayFragment: QrCodePayFragment? = null
+ private var cashPayFragment: CashPayFragment? = null
+ private var numberPayFragment: NumberPayFragment? = null
+ private var facePayFragment: FacePayFragment? = null
+ private var payResultFragment: PayResultFragment? = null
+
+ @Suppress("DEPRECATION")
+ override fun initialize() {
+ super.initialize()
+ foodInfo = intent.getParcelableExtra(FOOD_INFO)
+ binding.tvFoodName.text = foodInfo?.foodName
+ binding.include.ivPageBack.setOnClickListener { finish() }
+ binding.include.tvPageTitle.text = "下单结算"
+ val payQrCodeClickListener = View.OnClickListener {
+ if (qrCodePayFragment == null) {
+ qrCodePayFragment = QrCodePayFragment()
+ }
+ addFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE)
+ switchButton(true, false, false, false)
+ }
+ binding.btnPayQrCode.setOnClickListener(payQrCodeClickListener)
+ binding.btnPayCash.setOnClickListener {
+ if (cashPayFragment == null) {
+ cashPayFragment = CashPayFragment()
+ }
+ addFragment(cashPayFragment!!, TAG_PAY_CASH)
+ switchButton(false, true, false, false)
+ }
+ binding.btnPayNumber.setOnClickListener {
+ if (numberPayFragment == null) {
+ numberPayFragment = NumberPayFragment()
+ }
+ addFragment(numberPayFragment!!, TAG_PAY_NUMBER)
+ switchButton(false, false, true, false)
+ }
+ binding.btnPayFace.setOnClickListener {
+ showFacePay()
+ }
+
+ payQrCodeClickListener.onClick(binding.btnPayQrCode)
+ }
+
+ private fun switchButton(vararg arr: Boolean) {
+ binding.btnPayQrCode.isChecked = arr[0]
+ binding.btnPayCash.isChecked = arr[1]
+ binding.btnPayNumber.isChecked = arr[2]
+ binding.btnPayFace.isChecked = arr[3]
+ }
+
+ fun showFacePay() {
+ if (facePayFragment == null) {
+ facePayFragment = FacePayFragment()
+ }
+ addFragment(facePayFragment!!, TAG_PAY_FACE)
+ switchButton(false, false, false, true)
+ }
+
+ private fun addFragment(currentFragment: Fragment, tag: String) {
+ runCatching {
+ supportFragmentManager.beginTransaction().apply {
+ val existFragment = supportFragmentManager.findFragmentByTag(tag)
+ if (existFragment == null) {
+ add(R.id.fragmentContainerView, currentFragment, tag)
+ }
+ val fragments = supportFragmentManager.fragments
+ fragments.forEach {
+ it?.let { fragment ->
+ if (fragment != currentFragment) {
+ hide(fragment)
+ }
+ }
+ }
+ show(currentFragment)
+ commitAllowingStateLoss()
+ }
+ }.onFailure {
+ it.printStackTrace()
+ }
+ }
+
+ fun showPayResult() {
+ if (payResultFragment == null) {
+ payResultFragment = PayResultFragment()
+ }
+ addFragment(payResultFragment!!, TAG_PAY_RESULT)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/SettingActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/SettingActivity.kt
new file mode 100644
index 0000000..977bd4d
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/SettingActivity.kt
@@ -0,0 +1,71 @@
+package com.sw.dualscreen.activity
+
+import android.content.Intent
+import androidx.activity.viewModels
+import androidx.fragment.app.Fragment
+import com.sw.dualscreen.R
+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.viewmodel.BaseViewModel
+import com.sw.dualscreen.viewmodel.UserViewModel
+import kotlin.collections.get
+import kotlin.text.replace
+
+class SettingActivity : BaseActivity() {
+
+ private val viewModel by viewModels()
+ override fun getViewModel(): BaseViewModel {
+ return viewModel
+ }
+
+ override fun inflateViewBinding(): ActivitySettingBinding {
+ return ActivitySettingBinding.inflate(layoutInflater)
+ }
+
+ private val fragmentList = mutableListOf().apply {
+ add(BusinessFragment())
+ add(CollectFragment())
+ }
+
+ override fun initialize() {
+ super.initialize()
+ binding.include.let {
+ it.ivPageBack.setOnClickListener {
+ val intent = Intent(this, MainActivity::class.java)
+ startActivity(intent)
+ finish()
+ }
+ it.tvPageTitle.text = "设置"
+ }
+ binding.rgSetting.setOnCheckedChangeListener { group, checkedId ->
+ if (checkedId == R.id.rbBusiness) {
+ showFragment(fragmentList[0])
+ return@setOnCheckedChangeListener
+ }
+ if (checkedId == R.id.rbCollect) {
+
+ showFragment(fragmentList[1])
+ return@setOnCheckedChangeListener
+ }
+ }
+ binding.rgSetting.check(R.id.rbBusiness)
+ }
+
+ private fun showFragment(fragment: Fragment) {
+ runCatching {
+ supportFragmentManager.beginTransaction().apply {
+ replace(R.id.fragmentContainerView, fragment)
+ commit()
+ }
+ }.onFailure {
+ it.printStackTrace()
+ }
+ }
+
+ fun searchByFoodName(foodName:String, action: (List) -> Unit) {
+ viewModel.searchByFoodName(foodName, action)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/BaseFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/BaseFragment.kt
new file mode 100644
index 0000000..4559989
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/BaseFragment.kt
@@ -0,0 +1,32 @@
+package com.sw.dualscreen.activity.fragment
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.viewbinding.ViewBinding
+
+abstract class BaseFragment: Fragment() {
+
+ protected lateinit var binding: VB
+
+ protected abstract fun inflateViewBinding(): VB
+
+ abstract fun initialize()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = inflateViewBinding()
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ initialize()
+ }
+
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..1144834
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/BusinessFragment.kt
@@ -0,0 +1,42 @@
+package com.sw.dualscreen.activity.fragment
+
+import android.view.LayoutInflater
+import com.sw.dualscreen.GlobalKey
+import com.sw.dualscreen.R
+import com.sw.dualscreen.databinding.FragmentBusinessBinding
+import com.sw.dualscreen.sdk.SensorScaleUtils
+import com.sw.dualscreen.utils.SPUtil
+import kotlin.math.roundToInt
+
+class BusinessFragment: BaseFragment() {
+
+ override fun inflateViewBinding(): FragmentBusinessBinding {
+ return FragmentBusinessBinding.inflate(LayoutInflater.from(context))
+ }
+
+ override fun initialize() {
+ binding.rgCharge.let {
+ it.setOnCheckedChangeListener { group, checkedId ->
+ val mode = if (checkedId == R.id.rbChargeYes) 0 else 1
+ SPUtil.getInstance().put(GlobalKey.KEY_CHARGE_MODE, mode)
+ }
+ val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
+ it.check(if (mode == 0) R.id.rbChargeYes else R.id.rbChargeNot)
+ }
+ binding.rgTakeFood.let {
+ it.setOnCheckedChangeListener { group, checkedId ->
+ val mode = if (checkedId == R.id.rbPickAndPlace) 0 else 1
+ SPUtil.getInstance().put(GlobalKey.KEY_PICKUP_MODE, mode)
+ }
+ val mode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0)
+ it.check(if (mode == 0) R.id.rbPickAndPlace else R.id.rbSurplusCalculate)
+ }
+ binding.btnClearZero.setOnClickListener {
+ SensorScaleUtils.tare()
+ }
+ SensorScaleUtils.addWeightListener { value ->
+ val realWeight = (value * 1000).roundToInt()
+ binding.tvFoodWeight.text = "$realWeight"
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/CashPayFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/CashPayFragment.kt
new file mode 100644
index 0000000..64e5b32
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/CashPayFragment.kt
@@ -0,0 +1,25 @@
+package com.sw.dualscreen.activity.fragment
+
+import android.text.Spanned
+import android.text.SpannedString
+import android.text.style.AbsoluteSizeSpan
+import androidx.core.text.buildSpannedString
+import com.sw.dualscreen.databinding.FragmentCashPayBinding
+
+class CashPayFragment: BaseFragment() {
+
+ override fun inflateViewBinding(): FragmentCashPayBinding {
+ return FragmentCashPayBinding.inflate(layoutInflater)
+ }
+
+ override fun initialize() {
+ binding.tvRealAmount.text = getAmountText("36.8")
+ }
+
+ private fun getAmountText(amount:String): SpannedString {
+ return buildSpannedString {
+ append("¥", AbsoluteSizeSpan(36, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ append(amount, AbsoluteSizeSpan(60, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/CollectFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/CollectFragment.kt
new file mode 100644
index 0000000..4db19cd
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/CollectFragment.kt
@@ -0,0 +1,285 @@
+package com.sw.dualscreen.activity.fragment
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.view.LayoutInflater
+import android.view.View
+import android.view.inputmethod.EditorInfo
+import android.view.inputmethod.InputMethodManager
+import android.widget.Toast
+import androidx.camera.view.PreviewView
+import androidx.core.net.toUri
+import androidx.core.view.updateLayoutParams
+import androidx.recyclerview.widget.GridLayoutManager
+import com.sw.dualscreen.R
+import com.sw.dualscreen.activity.CollectedFoodActivity
+import com.sw.dualscreen.activity.SettingActivity
+import com.sw.dualscreen.adapter.FoodCollectionAdapter
+import com.sw.dualscreen.adapter.SearchFoodAdapter
+import com.sw.dualscreen.databinding.FragmentCollectBinding
+import com.sw.dualscreen.databinding.LayoutCameraPreviewBinding
+import com.sw.dualscreen.ext.clickWithDebounce
+import com.sw.dualscreen.ext.dp
+import com.sw.dualscreen.model.response.FoodInfo
+import com.sw.dualscreen.objbox.Food
+import com.sw.dualscreen.objbox.FoodCollectionBean
+import com.sw.dualscreen.objbox.FoodModule
+import com.sw.dualscreen.objbox.ObjectBox
+import com.sw.dualscreen.utils.BitmapSaver
+import com.sw.dualscreen.utils.CameraUtils
+import com.sw.dualscreen.utils.Debouncer
+import com.sw.dualscreen.utils.ImageUtil
+import com.sw.plate.utils.ToastUtils
+import io.objectbox.Box
+import io.objectbox.kotlin.boxFor
+import timber.log.Timber
+import kotlin.getValue
+
+class CollectFragment : BaseFragment() {
+
+ companion object {
+ const val MAX_COUNT = 5
+ }
+ private var selectedFoodId: String? = ""
+ private var selectedFoodName: String? = ""
+
+ private var box: Box? = null
+ private val foodCollectionList = mutableListOf().apply {
+ repeat(MAX_COUNT) {
+ add(FoodCollectionBean(isShowCamera = true))
+ }
+ }
+
+ private val searchFoodList = mutableListOf()
+ 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!!.id
+ val isChecked = checkedItem!!.isChecked
+ searchFoodList[position].isChecked = isChecked.not()
+ notifyItemChanged(position)
+ }
+ }
+ }
+ private val debouncer = Debouncer(2000)
+ private lateinit var previewView: PreviewView
+ private val cameraUtils: CameraUtils by lazy {
+ CameraUtils(requireActivity())
+ }
+
+ private val collectionAdapter: FoodCollectionAdapter by lazy {
+ FoodCollectionAdapter(foodCollectionList).apply {
+ addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
+ foodCollectionList[position].let {
+ it.bitmap = null
+ it.isShowCamera = true
+ it.isFinish = false
+ }
+ notifyItemChanged(position)
+ }
+ }
+ }
+ override fun inflateViewBinding(): FragmentCollectBinding {
+ return FragmentCollectBinding.inflate(LayoutInflater.from(context))
+ }
+
+
+ private val cameraCallback: (Uri) -> Unit = { uri ->
+ val index = foodCollectionList.indexOfFirst { it.bitmap == null }
+ if (index == -1) {
+ ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
+ rerurn@cameraCallback
+ }
+ ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap ->
+// val cropBitmap = BitmapCropper.cropCenter(
+// original = bitmap,
+// targetWidth = 1300, targetHeight = 900,
+// //offsetX = 30, offsetY = 100
+// )
+ val file = BitmapSaver.saveToAppFilesDir(
+ bitmap, requireActivity(), "IMG_CROP_${System.currentTimeMillis()}.jpg"
+ )
+ Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
+
+ foodCollectionList[index].let {
+ it.bitmap = bitmap
+ it.isShowCamera = false
+ it.imageUri = file?.toUri()
+ }
+ collectionAdapter.notifyItemChanged(index)
+ }
+ }
+
+ @SuppressLint("NotifyDataSetChanged")
+ private fun takePhoto() {
+ val count = foodCollectionList.count { it.bitmap != null }
+ if (count >= MAX_COUNT) {
+ ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
+ return
+ }
+ cameraUtils.takePhoto(cameraCallback)
+ }
+
+ override fun initialize() {
+ settingActivity = activity as SettingActivity
+ cameraUtils.initCamera()
+ val previewBinding =
+ LayoutCameraPreviewBinding.inflate(layoutInflater, binding.flCameraPreview)
+ previewView = previewBinding.previewView.also {
+ it.updateLayoutParams {
+ width = 456.dp
+ height = 342.dp
+ }
+ }
+ cameraUtils.setPreviewController(previewView)
+
+ binding.rvFoodList.let {
+ it.layoutManager = GridLayoutManager(requireActivity(), 3, GridLayoutManager.VERTICAL, false)
+ it.adapter = collectionAdapter
+ }
+
+ binding.btnFoodSearch.setOnClickListener {
+ searchInfo()
+ }
+
+ binding.btnSave.setOnClickListener {
+ if (selectedFoodName.isNullOrBlank()) {
+ Toast.makeText(requireActivity(), "请选择菜品名称", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+ if (foodCollectionList.size <= 1) {
+ Toast.makeText(requireActivity(), "请拍摄菜品照片", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+ vectorThread()
+ }
+
+ binding.editFoodName.setOnEditorActionListener { v, actionId, event ->
+ if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+ searchInfo()
+ val imm =
+ v.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(v.windowToken, 0)
+ true
+ } else {
+ false
+ }
+ }
+
+ binding.btnCollectedFood.setOnClickListener {
+ startActivity(Intent(requireActivity(), CollectedFoodActivity::class.java))
+ }
+ binding.btnTakePhoto.clickWithDebounce {
+ val count = foodCollectionList.count { it.bitmap != null }
+ if (count >= MAX_COUNT) {
+ ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
+ return@clickWithDebounce
+ }
+ takePhoto()
+ }
+ binding.btnClearData.setOnClickListener { clearData() }
+ binding.rvSearchFood.let {
+ it.layoutManager = GridLayoutManager(context, 2)
+ it.adapter = searchFoodAdapter
+ }
+ }
+
+ private fun vectorThread() {
+ settingActivity?.showWaitingDialog("加载中……")
+ Thread {
+ foodCollectionList
+ .filter { it.bitmap != null }
+ .forEachIndexed { index, it ->
+ image2VectorTask(it, index)
+ }
+ activity?.runOnUiThread {
+ binding.root.postDelayed({
+ settingActivity?.hideWaitingDialog()
+ }, 1000)
+ }
+ }.start()
+ }
+
+ private fun initBox() {
+ if (box == null) {
+ box = ObjectBox.boxStore.boxFor(Food::class)
+ }
+ }
+
+ private fun image2VectorTask(item: FoodCollectionBean, position: Int) {
+ initBox()
+ val imageVector = FoodModule.bitmap2FloatArray(item.bitmap!!)
+
+// val base64Str = FloatBase64Utils.floatArrayToBase64(imageVector)
+// Timber.tag("mzf1").e(base64Str)
+//// viewModel.postImageData(
+//// context,
+//// foodId = selectedFoodId.toString(),
+//// foodName = selectedFoodName.toString(),
+//// foodVector = base64Str,
+//// uri = item.imageUri!!
+//// )
+ box?.put(Food(name = checkedItem!!.foodName, foodIdx = 0, foodVector = imageVector))
+ foodCollectionList[position].let {
+ it.imageVector = imageVector
+ it.isFinish = true
+ }
+
+ activity?.runOnUiThread {
+ collectionAdapter.notifyItemChanged(position)
+ }
+ }
+
+
+ @SuppressLint("NotifyDataSetChanged")
+ private fun searchInfo() {
+ debouncer.debounce {
+ settingActivity?.searchByFoodName(binding.editFoodName.text.toString()) {
+ searchFoodList.clear()
+ searchFoodList.addAll(it)
+ searchFoodAdapter.notifyDataSetChanged()
+ }
+ }
+ }
+
+ private var clickIndex = -1
+
+ @SuppressLint("NotifyDataSetChanged")
+ private fun clearData() {
+ foodCollectionList.forEach {
+ it.bitmap = null
+ it.isShowCamera = true
+ it.isFinish = false
+ }
+ collectionAdapter.notifyDataSetChanged()
+
+ clickIndex = -1
+ binding.editFoodName.setText("")
+// foodList.clear()
+// foodAdapter.updateData(mutableListOf())
+// foodAdapter.notifyDataSetChanged()
+ //loadEmptyView()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ cameraUtils.bind()
+ binding.llCameraFlag.run {
+ visibility = View.VISIBLE
+ postDelayed({
+ visibility = View.GONE
+ }, 3000)
+ }
+ }
+
+ override fun onPause() {
+ super.onPause()
+ cameraUtils.unbind()
+ binding.llCameraFlag.visibility = View.VISIBLE
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/FacePayFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/FacePayFragment.kt
new file mode 100644
index 0000000..f89df12
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/FacePayFragment.kt
@@ -0,0 +1,19 @@
+package com.sw.dualscreen.activity.fragment
+
+import com.sw.dualscreen.activity.PayActivity
+import com.sw.dualscreen.databinding.FragmentFacePayBinding
+
+class FacePayFragment : BaseFragment() {
+
+ override fun inflateViewBinding(): FragmentFacePayBinding {
+ return FragmentFacePayBinding.inflate(layoutInflater)
+ }
+
+ private var payActivity: PayActivity? = null
+ override fun initialize() {
+ payActivity = activity as PayActivity
+ binding.tvFaceState.setOnClickListener {
+ payActivity?.showPayResult()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/NumberPayFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/NumberPayFragment.kt
new file mode 100644
index 0000000..a8ab754
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/NumberPayFragment.kt
@@ -0,0 +1,15 @@
+package com.sw.dualscreen.activity.fragment
+
+import com.sw.dualscreen.databinding.FragmentNumberPayBinding
+import com.sw.dualscreen.ext.hideKeyboard
+
+class NumberPayFragment: BaseFragment() {
+
+ override fun inflateViewBinding(): FragmentNumberPayBinding {
+ return FragmentNumberPayBinding.inflate(layoutInflater)
+ }
+
+ override fun initialize() {
+ binding.root.hideKeyboard()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/PayResultFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/PayResultFragment.kt
new file mode 100644
index 0000000..9cdb82b
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/PayResultFragment.kt
@@ -0,0 +1,28 @@
+package com.sw.dualscreen.activity.fragment
+
+import com.sw.dualscreen.activity.PayActivity
+import com.sw.dualscreen.databinding.FragmentPayResultBinding
+
+class PayResultFragment: BaseFragment() {
+
+ override fun inflateViewBinding(): FragmentPayResultBinding {
+ return FragmentPayResultBinding.inflate(layoutInflater)
+ }
+
+
+ private var payActivity: PayActivity? = null
+ override fun initialize() {
+ payActivity = activity as PayActivity
+ binding.btnBack.setOnClickListener {
+ payActivity?.showFacePay()
+ }
+ }
+
+ override fun onHiddenChanged(hidden: Boolean) {
+ super.onHiddenChanged(hidden)
+ //显示时重新查询接口
+ if (hidden.not()) {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/QrCodePayFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/QrCodePayFragment.kt
new file mode 100644
index 0000000..f19b823
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/QrCodePayFragment.kt
@@ -0,0 +1,29 @@
+package com.sw.dualscreen.activity.fragment
+
+import android.text.Spanned
+import android.text.SpannedString
+import android.text.style.AbsoluteSizeSpan
+import androidx.core.text.buildSpannedString
+import com.sw.dualscreen.R
+import com.sw.dualscreen.databinding.FragmentQrcodePayBinding
+
+class QrCodePayFragment: BaseFragment() {
+
+ override fun inflateViewBinding(): FragmentQrcodePayBinding {
+ return FragmentQrcodePayBinding.inflate(layoutInflater)
+ }
+
+ override fun initialize() {
+ binding.tvRealAmount.text = getAmountText("36.8")
+ binding.ivPayQrCode.setImageResource(R.drawable.ic_qrcode)
+ binding.tvPayResult.text = "待支付(60s)..."
+ }
+
+ private fun getAmountText(amount:String): SpannedString {
+ return buildSpannedString {
+ append("¥", AbsoluteSizeSpan(36, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ append(amount, AbsoluteSizeSpan(60, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/adapter/CollectedFoodAdapter.kt b/app/src/main/java/com/sw/dualscreen/adapter/CollectedFoodAdapter.kt
index c1471ef..fe24e3b 100644
--- a/app/src/main/java/com/sw/dualscreen/adapter/CollectedFoodAdapter.kt
+++ b/app/src/main/java/com/sw/dualscreen/adapter/CollectedFoodAdapter.kt
@@ -1,34 +1,34 @@
-package com.sw.dualscreen.adapter
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import com.chad.library.adapter4.BaseQuickAdapter
-import com.chad.library.adapter4.viewholder.QuickViewHolder
-import com.sw.dualscreen.R
-import com.sw.dualscreen.databinding.ListItemCollectedDataBinding
-import com.sw.dualscreen.databinding.ListItemFoodCollectionBinding
-import com.sw.dualscreen.objbox.CollectedFoodBean
-import com.sw.dualscreen.objbox.FoodCollectionBean
-
-class CollectedFoodAdapter (var list: MutableList) :
- BaseQuickAdapter(list) {
-
- inner class VH(var binding: ListItemCollectedDataBinding) : QuickViewHolder(binding.root)
-
- override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
- val inflater = LayoutInflater.from(context)
- val binding = ListItemCollectedDataBinding.inflate(inflater, parent, false)
- return VH(binding)
- }
-
- override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodBean?) {
- holder.binding.tvFoodName.text = item?.foodName
- holder.binding.divider.run {
- visibility = if (position == list.size - 1) View.GONE else View.VISIBLE
- }
- }
-
-}
\ No newline at end of file
+//package com.sw.dualscreen.adapter
+//
+//import android.content.Context
+//import android.view.LayoutInflater
+//import android.view.View
+//import android.view.ViewGroup
+//import android.widget.ImageView
+//import com.chad.library.adapter4.BaseQuickAdapter
+//import com.chad.library.adapter4.viewholder.QuickViewHolder
+//import com.sw.dualscreen.R
+//import com.sw.dualscreen.databinding.ListItemCollectedDataBinding
+//import com.sw.dualscreen.databinding.ListItemFoodCollectionBinding
+//import com.sw.dualscreen.objbox.CollectedFoodBean
+//import com.sw.dualscreen.objbox.FoodCollectionBean
+//
+//class CollectedFoodAdapter (var list: MutableList) :
+// BaseQuickAdapter(list) {
+//
+// inner class VH(var binding: ListItemCollectedDataBinding) : QuickViewHolder(binding.root)
+//
+// override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
+// val inflater = LayoutInflater.from(context)
+// val binding = ListItemCollectedDataBinding.inflate(inflater, parent, false)
+// return VH(binding)
+// }
+//
+// override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodBean?) {
+// holder.binding.tvFoodName.text = item?.foodName
+// holder.binding.divider.run {
+// visibility = if (position == list.size - 1) View.GONE else View.VISIBLE
+// }
+// }
+//
+//}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/adapter/CollectedFoodNewAdapter.kt b/app/src/main/java/com/sw/dualscreen/adapter/CollectedFoodNewAdapter.kt
new file mode 100644
index 0000000..17901ab
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/adapter/CollectedFoodNewAdapter.kt
@@ -0,0 +1,27 @@
+package com.sw.dualscreen.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.sw.dualscreen.databinding.ListItemCollectedFoodBinding
+import com.sw.dualscreen.objbox.CollectedFoodBean
+
+class CollectedFoodNewAdapter(var list: MutableList) :
+ BaseQuickAdapter(list) {
+
+ inner class VH(var binding: ListItemCollectedFoodBinding) : QuickViewHolder(binding.root)
+
+ override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
+ val inflater = LayoutInflater.from(context)
+ val binding = ListItemCollectedFoodBinding.inflate(inflater, parent, false)
+ return VH(binding)
+ }
+
+ override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodBean?) {
+ holder.binding.tvFoodName.text = item?.foodName
+ holder.binding.tvCollectedNum.text = "已采集153"
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/adapter/FoodCollectionAdapter.kt b/app/src/main/java/com/sw/dualscreen/adapter/FoodCollectionAdapter.kt
index 306112c..ea86512 100644
--- a/app/src/main/java/com/sw/dualscreen/adapter/FoodCollectionAdapter.kt
+++ b/app/src/main/java/com/sw/dualscreen/adapter/FoodCollectionAdapter.kt
@@ -9,7 +9,9 @@ import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.sw.dualscreen.R
import com.sw.dualscreen.databinding.ListItemFoodCollectionBinding
+import com.sw.dualscreen.ext.dp
import com.sw.dualscreen.objbox.FoodCollectionBean
+import com.sw.dualscreen.utils.GlideUtils
class FoodCollectionAdapter (var list: MutableList) :
BaseQuickAdapter(list) {
@@ -30,11 +32,20 @@ class FoodCollectionAdapter (var list: MutableList) :
binding.imageView.run {
if (it.isShowCamera) {
scaleType = ImageView.ScaleType.CENTER
- setImageResource(R.drawable.ic_camera256)
+ setImageResource(R.drawable.ic_camera_default)
} else {
- scaleType = ImageView.ScaleType.FIT_CENTER
+ //scaleType = ImageView.ScaleType.FIT_CENTER
+ scaleType = ImageView.ScaleType.CENTER_CROP
//setImageURI(it.imageUri)
- setImageBitmap(it.bitmap)
+ //setImageBitmap(it.bitmap)
+ it.bitmap?.let { bitmap ->
+ GlideUtils.loadRoundCornerWitBitmap(
+ context,
+ url = bitmap,
+ imageView = this,
+ radius = 8.dp
+ )
+ }
}
}
}
diff --git a/app/src/main/java/com/sw/dualscreen/adapter/SearchFoodAdapter.kt b/app/src/main/java/com/sw/dualscreen/adapter/SearchFoodAdapter.kt
new file mode 100644
index 0000000..f2f0078
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/adapter/SearchFoodAdapter.kt
@@ -0,0 +1,35 @@
+package com.sw.dualscreen.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.sw.dualscreen.databinding.ListItemSearchFoodBinding
+import com.sw.dualscreen.ext.format2String
+import com.sw.dualscreen.model.response.FoodInfo
+
+class SearchFoodAdapter(var list: MutableList) :
+ BaseQuickAdapter(list) {
+
+ inner class VH(var binding: ListItemSearchFoodBinding) : QuickViewHolder(binding.root)
+
+ override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
+ val inflater = LayoutInflater.from(context)
+ val binding = ListItemSearchFoodBinding.inflate(inflater, parent, false)
+ return VH(binding)
+ }
+
+ override fun onBindViewHolder(holder: VH, position: Int, item: FoodInfo?) {
+ holder.binding.tvFoodName.run {
+ if (item!!.score == 0) {
+ text = item.foodName
+ } else {
+ val score = (item.score / 100.0).format2String(2)
+ text = "${item.foodName}\n${score}%"
+ }
+ isChecked = item.isChecked
+ }
+ }
+
+}
\ No newline at end of file
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 4725fe8..d3529c7 100644
--- a/app/src/main/java/com/sw/dualscreen/ext/CommonExt.kt
+++ b/app/src/main/java/com/sw/dualscreen/ext/CommonExt.kt
@@ -120,3 +120,15 @@ fun View.clickWithDebounce(delay: Long = 500, action: () -> Unit) {
}
}
}
+
+fun View.visible() {
+ visibility = View.VISIBLE
+}
+
+fun View.invisible() {
+ visibility = View.INVISIBLE
+}
+
+fun View.gone() {
+ visibility = View.GONE
+}
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 7b584cc..0f1fc7a 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
@@ -39,7 +39,8 @@ data class FoodInfo(
val stFoodInfoSetting: StFoodInfoSetting? = StFoodInfoSetting(),
@SerializedName("stFoodInfoSpecificationList")
val stFoodInfoSpecificationList: List? = listOf(),
- var score: Int = 0
+ var score: Int = 0,
+ var isChecked: Boolean = false
) : Parcelable {
@Parcelize
data class FoodTypeAndRealIntakeVo(
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 04402f0..6ad5388 100644
--- a/app/src/main/java/com/sw/dualscreen/sdk/SensorScaleUtils.kt
+++ b/app/src/main/java/com/sw/dualscreen/sdk/SensorScaleUtils.kt
@@ -4,8 +4,10 @@ import com.sw.plate.utils.ToastUtils
import com.wabon.wbintelligenthardwaresdk.api.SensorScale
import com.wabon.wbintelligenthardwaresdk.api.SensorScale.OnScaleResult
import timber.log.Timber
+import kotlin.math.roundToInt
typealias Callback = (Double) -> Unit
+typealias WeightCallback = (Double) -> Unit
private const val TAG = "SensorScaleUtils"
@@ -41,6 +43,10 @@ object SensorScaleUtils {
lastWeight = value
callback?.invoke(value)
}
+
+ weightCallbackList.forEach {
+ it.invoke(value)
+ }
}
/**
@@ -60,7 +66,7 @@ object SensorScaleUtils {
* 开启称重
* @param autoScale 是否开启自动读取
*/
- fun startScale(autoScale: Boolean = true, callback: Callback?) {
+ fun startScale(autoScale: Boolean = true, callback: Callback? = null) {
Timber.d("startScale isOpened = $isOpened")
if (isOpened) {
startContinuousRead(callback = callback)
@@ -112,6 +118,13 @@ object SensorScaleUtils {
mSensorScale?.readWeight()
}
+ private var weightCallbackList: MutableList = mutableListOf()
+ fun addWeightListener(weightCallback: WeightCallback) {
+ if (weightCallbackList.contains(weightCallback).not()) {
+ weightCallbackList.add(weightCallback)
+ }
+ }
+
/**
* 零位标定
*/
diff --git a/app/src/main/java/com/sw/dualscreen/utils/ActivityManager.kt b/app/src/main/java/com/sw/dualscreen/utils/ActivityManager.kt
new file mode 100644
index 0000000..0937ba8
--- /dev/null
+++ b/app/src/main/java/com/sw/dualscreen/utils/ActivityManager.kt
@@ -0,0 +1,57 @@
+package com.sw.dualscreen.utils
+
+import android.app.Activity
+import android.os.Process
+import java.util.Stack
+
+object ActivityManager {
+
+ private val activityStack = Stack()
+
+ // 添加Activity到栈
+ fun addActivity(activity: Activity) {
+ activityStack.add(activity)
+ }
+
+ // 移除指定Activity
+ fun removeActivity(activity: Activity) {
+ activityStack.remove(activity)
+ }
+
+ // 获取当前Activity
+ fun currentActivity(): Activity? {
+ return if (activityStack.isEmpty()) null else activityStack.lastElement()
+ }
+
+ // 结束指定Activity
+ fun finishActivity(activity: Activity) {
+ if (!activity.isFinishing) {
+ activity.finish()
+ }
+ }
+
+ // 结束所有Activity
+ fun finishAllActivity() {
+ activityStack.forEach {
+ if (!it.isFinishing) {
+ it.finish()
+ }
+ }
+ activityStack.clear()
+ }
+
+ // 退出应用程序
+ fun exitApp() {
+ finishAllActivity()
+ Process.killProcess(Process.myPid())
+ }
+
+ fun getActivityStack(): Stack{
+ return activityStack
+ }
+
+ fun isEmpty() : Boolean {
+ return activityStack.isEmpty()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/dualscreen/utils/GlideUtils.kt b/app/src/main/java/com/sw/dualscreen/utils/GlideUtils.kt
index a0aa45f..3581e75 100644
--- a/app/src/main/java/com/sw/dualscreen/utils/GlideUtils.kt
+++ b/app/src/main/java/com/sw/dualscreen/utils/GlideUtils.kt
@@ -104,6 +104,21 @@ object GlideUtils {
.into(imageView)
}
+ fun loadRoundCornerWitBitmap(
+ context: Context,
+ url: Bitmap,
+ imageView: ImageView,
+ radius: Int,
+ @DrawableRes placeholderResId: Int = 0,
+ @DrawableRes errorResId: Int = 0
+ ) {
+ val requestBuilder = Glide.with(context)
+ .load(url)
+ .apply(RequestOptions.bitmapTransform(RoundedCorners(radius)))
+
+ applyPlaceholder(requestBuilder, placeholderResId, errorResId)
+ .into(imageView)
+ }
/**
* 加载图片并获取Bitmap
* @param context 上下文
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 abf66d1..724eb91 100644
--- a/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt
+++ b/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt
@@ -158,12 +158,14 @@ class UserViewModel : BaseViewModel() {
/**
* 搜索食物
*/
- fun searchByFoodName(foodName: String) {
+ fun searchByFoodName(foodName: String, action: (List) -> Unit = {}) {
Timber.d("searchByFoodName foodName = $foodName")
launchWithLoading {
val response = repository.getRestInfoFoodsByType(foodName = foodName)
if (parseResponse(response)) {
- _searchFoodInfoList.value = response.result ?: emptyList()
+ val list = response.result ?: emptyList()
+ action(list)
+ _searchFoodInfoList.value = list
}
}
}
diff --git a/app/src/main/res/color/color_search_food.xml b/app/src/main/res/color/color_search_food.xml
new file mode 100644
index 0000000..e6c6fd0
--- /dev/null
+++ b/app/src/main/res/color/color_search_food.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/setting_radio.xml b/app/src/main/res/color/setting_radio.xml
new file mode 100644
index 0000000..e6c6fd0
--- /dev/null
+++ b/app/src/main/res/color/setting_radio.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xxhdpi/face_mask.png b/app/src/main/res/drawable-xxhdpi/face_mask.png
new file mode 100644
index 0000000..6cb6f06
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/face_mask.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_right.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_right.png
new file mode 100644
index 0000000..cb7df73
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_arrow_right.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_back2.png b/app/src/main/res/drawable-xxhdpi/ic_back2.png
new file mode 100644
index 0000000..d1644c1
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_back2.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_camera_default.png b/app/src/main/res/drawable-xxhdpi/ic_camera_default.png
new file mode 100644
index 0000000..c63a559
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_camera_default.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_close2.png b/app/src/main/res/drawable-xxhdpi/ic_close2.png
new file mode 100644
index 0000000..a6d77e4
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_close2.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_del2.png b/app/src/main/res/drawable-xxhdpi/ic_del2.png
new file mode 100644
index 0000000..8456dff
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_del2.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_delete_red.png b/app/src/main/res/drawable-xxhdpi/ic_delete_red.png
index ff00640..8456dff 100644
Binary files a/app/src/main/res/drawable-xxhdpi/ic_delete_red.png and b/app/src/main/res/drawable-xxhdpi/ic_delete_red.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_pay_success.png b/app/src/main/res/drawable-xxhdpi/ic_pay_success.png
new file mode 100644
index 0000000..f14edb9
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_pay_success.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_qrcode.png b/app/src/main/res/drawable-xxhdpi/ic_qrcode.png
new file mode 100644
index 0000000..95920a3
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_qrcode.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_retake_photo.png b/app/src/main/res/drawable-xxhdpi/ic_retake_photo.png
new file mode 100644
index 0000000..62e6b7e
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_retake_photo.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_search2.png b/app/src/main/res/drawable-xxhdpi/ic_search2.png
new file mode 100644
index 0000000..17e266d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_search2.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_setting.png b/app/src/main/res/drawable-xxhdpi/ic_setting.png
new file mode 100644
index 0000000..9936850
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_setting.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_setting_checked.png b/app/src/main/res/drawable-xxhdpi/ic_setting_checked.png
new file mode 100644
index 0000000..b9cebb2
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_setting_checked.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_take_photo.png b/app/src/main/res/drawable-xxhdpi/ic_take_photo.png
new file mode 100644
index 0000000..952051d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_take_photo.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_vip_level.png b/app/src/main/res/drawable-xxhdpi/ic_vip_level.png
new file mode 100644
index 0000000..f18bc68
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_vip_level.png differ
diff --git a/app/src/main/res/drawable/bg_border_red.xml b/app/src/main/res/drawable/bg_border_red.xml
new file mode 100644
index 0000000..751bec1
--- /dev/null
+++ b/app/src/main/res/drawable/bg_border_red.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_btn_clear.xml b/app/src/main/res/drawable/bg_btn_clear.xml
new file mode 100644
index 0000000..86ea423
--- /dev/null
+++ b/app/src/main/res/drawable/bg_btn_clear.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_btn_confirm.xml b/app/src/main/res/drawable/bg_btn_confirm.xml
new file mode 100644
index 0000000..4b76298
--- /dev/null
+++ b/app/src/main/res/drawable/bg_btn_confirm.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_btn_save.xml b/app/src/main/res/drawable/bg_btn_save.xml
new file mode 100644
index 0000000..d0c6549
--- /dev/null
+++ b/app/src/main/res/drawable/bg_btn_save.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_btn_save2.xml b/app/src/main/res/drawable/bg_btn_save2.xml
new file mode 100644
index 0000000..771f6c6
--- /dev/null
+++ b/app/src/main/res/drawable/bg_btn_save2.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_gray2.xml b/app/src/main/res/drawable/bg_gray2.xml
new file mode 100644
index 0000000..d499b62
--- /dev/null
+++ b/app/src/main/res/drawable/bg_gray2.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_pay_content.xml b/app/src/main/res/drawable/bg_pay_content.xml
new file mode 100644
index 0000000..769a644
--- /dev/null
+++ b/app/src/main/res/drawable/bg_pay_content.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_search_food.xml b/app/src/main/res/drawable/bg_search_food.xml
new file mode 100644
index 0000000..e71abfc
--- /dev/null
+++ b/app/src/main/res/drawable/bg_search_food.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/line_shape.xml b/app/src/main/res/drawable/line_shape.xml
new file mode 100644
index 0000000..7a0315c
--- /dev/null
+++ b/app/src/main/res/drawable/line_shape.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/setting_border.xml b/app/src/main/res/drawable/setting_border.xml
new file mode 100644
index 0000000..b744f3a
--- /dev/null
+++ b/app/src/main/res/drawable/setting_border.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/setting_border_gray.xml b/app/src/main/res/drawable/setting_border_gray.xml
new file mode 100644
index 0000000..4b57809
--- /dev/null
+++ b/app/src/main/res/drawable/setting_border_gray.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/setting_border_gray2.xml b/app/src/main/res/drawable/setting_border_gray2.xml
new file mode 100644
index 0000000..da566f9
--- /dev/null
+++ b/app/src/main/res/drawable/setting_border_gray2.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/setting_border_gray3.xml b/app/src/main/res/drawable/setting_border_gray3.xml
new file mode 100644
index 0000000..49ae121
--- /dev/null
+++ b/app/src/main/res/drawable/setting_border_gray3.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/setting_border_gray4.xml b/app/src/main/res/drawable/setting_border_gray4.xml
new file mode 100644
index 0000000..4b57809
--- /dev/null
+++ b/app/src/main/res/drawable/setting_border_gray4.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/setting_check_selector.xml b/app/src/main/res/drawable/setting_check_selector.xml
new file mode 100644
index 0000000..44bc631
--- /dev/null
+++ b/app/src/main/res/drawable/setting_check_selector.xml
@@ -0,0 +1,27 @@
+
+
+ -
+
+
-
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/vip_level.xml b/app/src/main/res/drawable/vip_level.xml
new file mode 100644
index 0000000..ac99d9e
--- /dev/null
+++ b/app/src/main/res/drawable/vip_level.xml
@@ -0,0 +1,13 @@
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_collected_food.xml b/app/src/main/res/layout/activity_collected_food.xml
new file mode 100644
index 0000000..bcdb30d
--- /dev/null
+++ b/app/src/main/res/layout/activity_collected_food.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index feaaddf..0f7dc33 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -4,7 +4,7 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@mipmap/bg"
+ android:background="#FFE7EFF8"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".activity.MainActivity">
@@ -12,25 +12,44 @@
+ android:layout_height="150dp">
-
+ android:layout_gravity="center_vertical"
+ android:layout_marginStart="32dp"
+ android:textColor="#ff0a1428"
+ android:textSize="30sp"
+ android:textStyle="bold"
+ tools:text="2025年11月11日 周二" />
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -91,7 +110,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="未识别出菜品,请重试或手动搜索"
- android:textColor="@color/white"
+ android:textColor="#FFFF3232"
android:textSize="24sp" />
@@ -111,11 +130,32 @@
android:id="@+id/tv_to_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="90dp"
- android:layout_marginBottom="90dp"
+ android:layout_marginTop="40dp"
+ android:layout_marginBottom="60dp"
android:padding="10dp"
android:text="以上都不是,手动搜索"
- android:textColor="#ffff9900"
+ android:textStyle="bold"
+ android:textColor="#FFFF3232"
android:textSize="36sp" />
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_pay.xml b/app/src/main/res/layout/activity_pay.xml
index d1cfb38..75eba32 100644
--- a/app/src/main/res/layout/activity_pay.xml
+++ b/app/src/main/res/layout/activity_pay.xml
@@ -1,21 +1,43 @@
+ android:orientation="vertical"
+ tools:ignore="HardcodedText">
-
+
+
+
+
+ android:layout_marginHorizontal="32dp"
+ android:layout_weight="1"
+ android:background="@drawable/bg_pay_content" />
diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml
new file mode 100644
index 0000000..baa4e8e
--- /dev/null
+++ b/app/src/main/res/layout/activity_setting.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_business.xml b/app/src/main/res/layout/fragment_business.xml
new file mode 100644
index 0000000..47b06a5
--- /dev/null
+++ b/app/src/main/res/layout/fragment_business.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_cash_pay.xml b/app/src/main/res/layout/fragment_cash_pay.xml
new file mode 100644
index 0000000..4f66683
--- /dev/null
+++ b/app/src/main/res/layout/fragment_cash_pay.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_collect.xml b/app/src/main/res/layout/fragment_collect.xml
new file mode 100644
index 0000000..22aa04f
--- /dev/null
+++ b/app/src/main/res/layout/fragment_collect.xml
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_face_pay.xml b/app/src/main/res/layout/fragment_face_pay.xml
new file mode 100644
index 0000000..d7e4a67
--- /dev/null
+++ b/app/src/main/res/layout/fragment_face_pay.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_number_pay.xml b/app/src/main/res/layout/fragment_number_pay.xml
new file mode 100644
index 0000000..e041d77
--- /dev/null
+++ b/app/src/main/res/layout/fragment_number_pay.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_pay_result.xml b/app/src/main/res/layout/fragment_pay_result.xml
new file mode 100644
index 0000000..f13b590
--- /dev/null
+++ b/app/src/main/res/layout/fragment_pay_result.xml
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_qrcode_pay.xml b/app/src/main/res/layout/fragment_qrcode_pay.xml
new file mode 100644
index 0000000..fe6c468
--- /dev/null
+++ b/app/src/main/res/layout/fragment_qrcode_pay.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_title_bar.xml b/app/src/main/res/layout/layout_title_bar.xml
new file mode 100644
index 0000000..1ff98b7
--- /dev/null
+++ b/app/src/main/res/layout/layout_title_bar.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_item_collected_food.xml b/app/src/main/res/layout/list_item_collected_food.xml
new file mode 100644
index 0000000..139245e
--- /dev/null
+++ b/app/src/main/res/layout/list_item_collected_food.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_item_food_collection.xml b/app/src/main/res/layout/list_item_food_collection.xml
index b4462ab..1f53c86 100644
--- a/app/src/main/res/layout/list_item_food_collection.xml
+++ b/app/src/main/res/layout/list_item_food_collection.xml
@@ -1,31 +1,30 @@
+ android:layout_width="212dp"
+ android:layout_height="159dp"
+ android:layout_margin="16dp"
+ android:background="@drawable/bg_gray2">
+ tools:src="@drawable/ic_camera_default" />
diff --git a/app/src/main/res/layout/list_item_search_food.xml b/app/src/main/res/layout/list_item_search_food.xml
new file mode 100644
index 0000000..72d9bfb
--- /dev/null
+++ b/app/src/main/res/layout/list_item_search_food.xml
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file