feat(activity): 新增食材识别页面,重构识别流程并优化多设备布局适配

This commit is contained in:
2026-04-16 18:05:46 +08:00
parent ad63639f66
commit 7373ccacbb
13 changed files with 413 additions and 48 deletions
+5
View File
@@ -111,6 +111,11 @@
android:theme="@style/Theme.DishMatch.NoSplash" android:theme="@style/Theme.DishMatch.NoSplash"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" /> tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name="com.shuwei.dish.match.ui.FoodRecognizeActivity"
android:theme="@style/Theme.DishMatch.NoSplash"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity <activity
android:name="com.shuwei.dish.match.ui.SlaveActivity" android:name="com.shuwei.dish.match.ui.SlaveActivity"
android:theme="@style/Theme.DishMatch.NoSplash" android:theme="@style/Theme.DishMatch.NoSplash"
@@ -66,7 +66,9 @@ class Scale18GridAdapter : BaseQuickAdapter<ScaleData, Scale18GridAdapter.VH>(mu
b.root.layoutParams = (b.root.layoutParams as ViewGroup.MarginLayoutParams).also { b.root.layoutParams = (b.root.layoutParams as ViewGroup.MarginLayoutParams).also {
it.width = cellSize it.width = cellSize
it.height = cellSize it.height = cellSize
it.setMargins(margin, margin, margin, margin) // 第1行:顶部间距为0,底部间距2dp,左右保持原有 margin
if (viewType == 0) it.setMargins(margin, 0, margin, 2.dp)
else it.setMargins(margin, margin, margin, margin)
} }
val baseSp = (cellSize / parent.resources.displayMetrics.density).toInt() val baseSp = (cellSize / parent.resources.displayMetrics.density).toInt()
b.tvAddr.textSize = (baseSp * 0.16f).coerceIn(9f, 14f) b.tvAddr.textSize = (baseSp * 0.16f).coerceIn(9f, 14f)
@@ -26,6 +26,7 @@ import com.shuwei.dish.match.entity.SeasoningEntity
import com.shuwei.dish.match.net.NetViewModel import com.shuwei.dish.match.net.NetViewModel
import com.shuwei.dish.match.ui.InitActivity import com.shuwei.dish.match.ui.InitActivity
import com.shuwei.dish.match.utils.ActivityManager import com.shuwei.dish.match.utils.ActivityManager
import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.gone import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.invisible import com.shuwei.dish.match.utils.ext.invisible
import com.shuwei.dish.match.utils.ext.visible import com.shuwei.dish.match.utils.ext.visible
@@ -65,6 +66,10 @@ open class BaseActivity : AppCompatActivity() {
// systemBarsBehavior = // systemBarsBehavior =
// WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE // 滑动时临时显示 // WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE // 滑动时临时显示
// } // }
// 主设备垂直 padding 30dp,子设备 15dp
val verticalPadding = if (GlobalData.deviceRole == DeviceRole.MASTER) 30.dp else 10.dp
binding.tvLeftTime.setPadding(0, verticalPadding, 0, verticalPadding)
binding.tvRightTime.setPadding(0, verticalPadding, 0, verticalPadding)
binding.llTitleBar.gone() binding.llTitleBar.gone()
binding.ivBack.setOnClickListener { finish() } binding.ivBack.setOnClickListener { finish() }
} }
@@ -7,7 +7,11 @@ import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.Window import android.view.Window
import android.widget.LinearLayout
import androidx.annotation.StyleRes import androidx.annotation.StyleRes
import androidx.core.view.updateLayoutParams
import com.shuwei.dish.match.base.DeviceRole
import com.shuwei.dish.match.base.GlobalData
import com.shuwei.dish.match.databinding.DialogCommonBinding import com.shuwei.dish.match.databinding.DialogCommonBinding
import com.shuwei.dish.match.utils.ext.dp import com.shuwei.dish.match.utils.ext.dp
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@@ -55,12 +59,17 @@ open class CommonDialog(
binding = DialogCommonBinding.inflate(layoutInflater) binding = DialogCommonBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
window?.run { window?.run {
val screenWidth = context.resources.displayMetrics.widthPixels
val isMaster = GlobalData.deviceRole == DeviceRole.MASTER
attributes = attributes.apply { attributes = attributes.apply {
width = 660.dp width = if (isMaster) (screenWidth * 0.72f).toInt() else (screenWidth * 0.60f).toInt()
} }
setBackgroundDrawable(ColorDrawable()) setBackgroundDrawable(ColorDrawable())
setCancelable(false) setCancelable(false)
} }
val verticalMargin = if (GlobalData.deviceRole == DeviceRole.MASTER) 35.dp else 20.dp
binding.tvTitle.updateLayoutParams<LinearLayout.LayoutParams> { topMargin = verticalMargin }
binding.tvContent.updateLayoutParams<LinearLayout.LayoutParams> { bottomMargin = verticalMargin }
binding.btnLeft.setOnClickListener { binding.btnLeft.setOnClickListener {
negativeClick?.invoke() negativeClick?.invoke()
dismiss() dismiss()
@@ -66,10 +66,10 @@ class LoadingDialog(
setCancelable(true) setCancelable(true)
window?.run { window?.run {
setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
setFlags( // setFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, // WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE // WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
); // );
} }
setOnDismissListener { setOnDismissListener {
onDismiss() onDismiss()
@@ -0,0 +1,213 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.recyclerview.widget.GridLayoutManager
import com.shuwei.dish.match.adapter.GoodsInfoSearchAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.ActivityFoodRecognizeBinding
import com.shuwei.dish.match.dialog.FoodSearchDialog
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
import com.shuwei.dish.match.utils.ActivityManager
import com.shuwei.dish.match.utils.AddressUtil
import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.visible
/**
* 食材识别结果页面
* 展示识别到的食材照片、食材列表、选中食材名称及秤1重量
*/
class FoodRecognizeActivity : BaseActivity() {
companion object {
private const val TAG = "FoodRecognizeActivity"
private const val EXTRA_IMAGE_URI = "extra_image_uri"
const val EXTRA_SELECTED_ITEM = "extra_selected_item"
/** 内存缓存食材列表,避免通过 Intent 序列化传递大数据 */
private var pendingGoodsList: ArrayList<CookFoodGoodsEntity>? = null
/**
* 启动本页面,通过 onResult 回调返回用户选中的食材
* @param activity 宿主 Activity
* @param imageUri 食材照片路径(可为空)
* @param goodsList 识别到的食材列表
* @param onResult 页面关闭后回调,携带用户选中的食材(未选中时为 null)
*/
fun start(
activity: BaseActivity,
imageUri: String? = null,
goodsList: ArrayList<CookFoodGoodsEntity> = arrayListOf(),
onResult: (CookFoodGoodsEntity?) -> Unit = {}
) {
pendingGoodsList = goodsList
val intent = Intent(activity, FoodRecognizeActivity::class.java).apply {
putExtra(EXTRA_IMAGE_URI, imageUri)
}
activity.startActivity(intent) { resultIntent ->
@Suppress("DEPRECATION")
val item = resultIntent?.getSerializableExtra(EXTRA_SELECTED_ITEM) as? CookFoodGoodsEntity
onResult(item)
}
}
/**
* 关闭当前识别页面,并将选中食材通过 Activity Result 回传
* 由外部(如重量归零时)调用
*/
fun close() {
ActivityManager.getActivityStack()
.filterIsInstance<FoodRecognizeActivity>()
.lastOrNull()
?.finishWithResult()
}
}
private lateinit var binding: ActivityFoodRecognizeBinding
private val list = mutableListOf<CookFoodGoodsEntity>()
private val adapter = GoodsInfoSearchAdapter(list).apply {
setOnItemClickListener { _, _, position ->
// 更新选中状态
list.forEachIndexed { i, item -> item.isClicked = (i == position) }
notifyDataSetChanged()
// 同步更新选中食材名称
binding.tvSelectedFood.text = list[position].goodsName ?: "-"
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityFoodRecognizeBinding.inflate(layoutInflater)
setContentView(binding.root)
setHeaderBackground()
// 显示标题栏
setTitleBar(titleBarAction = { it.visible() }, titleAction = { it.text = "食材识别" })
initData()
initRecyclerView()
initClickListeners()
registerWeightListener()
}
/**
* 从 Intent 读取数据并初始化页面
*/
private fun initData() {
// 加载食材照片
val imageUri = intent.getStringExtra(EXTRA_IMAGE_URI)
if (!imageUri.isNullOrBlank()) {
binding.ivFoodPhoto.setImageURI(Uri.parse(imageUri))
}
// 取出内存缓存的食材列表,取用后立即清空
val goodsList = pendingGoodsList?.also { pendingGoodsList = null }
if (!goodsList.isNullOrEmpty()) {
list.addAll(goodsList)
// 默认选中第一项
list[0].isClicked = true
binding.tvSelectedFood.text = list[0].goodsName ?: "-"
}
}
/**
* 初始化 RecyclerView
*/
private fun initRecyclerView() {
binding.recyclerView.run {
layoutManager = GridLayoutManager(this@FoodRecognizeActivity, 2)
adapter = this@FoodRecognizeActivity.adapter
}
updateListVisibility()
}
/**
* 根据列表是否有数据控制 RecyclerView 显隐
*/
private fun updateListVisibility() {
if (list.isEmpty()) {
binding.recyclerView.gone()
} else {
binding.recyclerView.visible()
}
}
/**
* 初始化按钮点击事件
*/
private fun initClickListeners() {
// 更换食材:打开食材搜索弹窗
binding.btnChangeFood.clickWithDebounce {
val currentName = if (list.isNotEmpty()) list.firstOrNull { it.isClicked }?.goodsName else null
FoodSearchDialog(
activity = this,
defGoodsName = currentName,
onItemSelected = { item ->
// 用搜索结果替换当前选中食材
updateSelectedFood(item)
}
).show()
}
// 取消:关闭页面
binding.btnCancel.setOnClickListener { finish() }
}
/**
* 用新食材替换当前选中项(或追加到列表首位)
*/
@SuppressLint("NotifyDataSetChanged")
private fun updateSelectedFood(item: CookFoodGoodsEntity) {
item.isClicked = true
val clickedIndex = list.indexOfFirst { it.isClicked && it.goodsId != item.goodsId }
if (clickedIndex >= 0) {
list[clickedIndex].isClicked = false
}
// 若列表中已存在则直接选中,否则插入到首位
val existIndex = list.indexOfFirst { it.goodsId == item.goodsId }
if (existIndex >= 0) {
list.forEachIndexed { i, e -> e.isClicked = (i == existIndex) }
} else {
list.add(0, item)
}
adapter.notifyDataSetChanged()
binding.tvSelectedFood.text = item.goodsName ?: "-"
updateListVisibility()
}
/**
* 注册秤1重量监听
*/
private fun registerWeightListener() {
WeightUtil.addWeightListener(TAG) { address, _, weight ->
if (address == AddressUtil.ONE) {
runOnUiThread {
binding.tvWeight.text = "$weight g"
}
}
}
}
/**
* 携带当前选中食材关闭页面
*/
private fun finishWithResult() {
val selected = list.firstOrNull { it.isClicked }
val intent = Intent().apply {
selected?.let { putExtra(EXTRA_SELECTED_ITEM, it) }
}
setResult(RESULT_OK, intent)
finish()
}
override fun onDestroy() {
super.onDestroy()
WeightUtil.removeWeightListener(TAG)
}
}
@@ -12,7 +12,6 @@ import com.shuwei.dish.match.adapter.DishPartAdapter
import com.shuwei.dish.match.base.BaseActivity import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.ActivityPrepareCookBinding import com.shuwei.dish.match.databinding.ActivityPrepareCookBinding
import com.shuwei.dish.match.dialog.CommonDialog import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.dialog.FoodRecognizeDialog
import com.shuwei.dish.match.dialog.FoodSearchDialog import com.shuwei.dish.match.dialog.FoodSearchDialog
import com.shuwei.dish.match.entity.CookFoodEntity import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.entity.CookFoodGoodsEntity import com.shuwei.dish.match.entity.CookFoodGoodsEntity
@@ -158,6 +157,10 @@ class PrepareCookActivity : BaseActivity() {
} }
private val isTakingPhoto = AtomicBoolean(false) private val isTakingPhoto = AtomicBoolean(false)
private var isRecognizeOpen = false
// 页面可见时允许识别,onPause 后禁止,onResume 后恢复
private var isRecognizeEnabled = true
private var lastPhotoUri: Uri? = null
private var lastWeight = 0.0 private var lastWeight = 0.0
private var currentWeight = 0.0 private var currentWeight = 0.0
@@ -168,10 +171,11 @@ class PrepareCookActivity : BaseActivity() {
private fun recognizeFood(weight: Double) { private fun recognizeFood(weight: Double) {
this.currentWeight = weight this.currentWeight = weight
if (weight < WEIGHT_RECOGNIZE_VALUE) { if (weight < WEIGHT_RECOGNIZE_VALUE) {
if (recognizeDialog.isShowing) recognizeDialog.dismiss() isRecognizeOpen = false
FoodRecognizeActivity.close()
return return
} }
if (isTakingPhoto.get() || recognizeDialog.isShowing || abs(lastWeight - weight) <= WEIGHT_CHANGE_VALUE) return if (!isRecognizeEnabled || isTakingPhoto.get() || isRecognizeOpen || abs(lastWeight - weight) <= WEIGHT_CHANGE_VALUE) return
isTakingPhoto.set(true) isTakingPhoto.set(true)
cameraUtils.takePhoto( cameraUtils.takePhoto(
succCallback = cameraSuccessCallback, succCallback = cameraSuccessCallback,
@@ -194,9 +198,13 @@ class PrepareCookActivity : BaseActivity() {
// materialType = // materialType =
isNewDishType = true isNewDishType = true
isOriginalData = false isOriginalData = false
useWeight = lastWeight
isSetFinished = true
}) })
onFoodItemClick(list.size - 1) val positon = list.size - 1
binding.rvDishPartList.smoothScrollToPosition(list.size - 1) dishPartAdapter.notifyItemInserted(positon)
onFoodItemClick(positon)
binding.rvDishPartList.smoothScrollToPosition(positon)
} }
/** /**
@@ -298,18 +306,24 @@ class PrepareCookActivity : BaseActivity() {
private var firstReqSize = 0 private var firstReqSize = 0
private val list = mutableListOf<CookFoodGoodsEntity>() private val list = mutableListOf<CookFoodGoodsEntity>()
private val recognizeDialog by lazy {
FoodRecognizeDialog(
activity = this,
onDismiss = { isTakingPhoto.set(false) },
onItemSelected = foodSelectCallback
)
}
private val dishPartAdapter by lazy { private val dishPartAdapter by lazy {
DishPartAdapter(list).apply { DishPartAdapter(list).apply {
setOnItemClickListener { _, _, positon -> setOnItemClickListener { _, _, positon ->
onFoodItemClick(positon) onFoodItemClick(positon)
} }
addOnItemChildClickListener(R.id.ivClearIcon) { _, _, positon ->
if (list[positon].isOriginalData) {
list[positon].run {
isNewDishType = false
isOriginalData = false
useWeight = 0.0
isSetFinished = false
}
notifyItemChanged(positon)
return@addOnItemChildClickListener
}
removeAt(positon)
}
} }
} }
@@ -388,11 +402,14 @@ class PrepareCookActivity : BaseActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
isRecognizeEnabled = true
isRecognizeOpen = false
cameraUtils.bind() cameraUtils.bind()
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
isRecognizeEnabled = false
cameraUtils.unbind() cameraUtils.unbind()
} }
@@ -438,6 +455,7 @@ class PrepareCookActivity : BaseActivity() {
*/ */
private val cameraSuccessCallback: (Uri) -> Unit = { uri -> private val cameraSuccessCallback: (Uri) -> Unit = { uri ->
Log.d(TAG, "takePhoto success") Log.d(TAG, "takePhoto success")
lastPhotoUri = uri
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val bitmap = ImageUtil.uriToBitmap(this@PrepareCookActivity, uri) val bitmap = ImageUtil.uriToBitmap(this@PrepareCookActivity, uri)
@@ -485,7 +503,13 @@ class PrepareCookActivity : BaseActivity() {
foodId = index.toString() foodId = index.toString()
)) ))
} }
recognizeDialog.loadData(foodList) FoodRecognizeActivity.start(
activity = this,
imageUri = lastPhotoUri?.toString(),
goodsList = ArrayList(foodList),
onResult = { item -> item?.let { foodSelectCallback(it) } }
)
isRecognizeOpen = true
isTakingPhoto.set(false) isTakingPhoto.set(false)
lastWeight = currentWeight lastWeight = currentWeight
} }
@@ -2,8 +2,10 @@ package com.shuwei.dish.match.ui
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Bundle import android.os.Bundle
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import android.widget.LinearLayout
import androidx.activity.addCallback import androidx.activity.addCallback
import com.google.android.flexbox.AlignItems import com.google.android.flexbox.AlignItems
import com.google.android.flexbox.FlexDirection import com.google.android.flexbox.FlexDirection
@@ -74,7 +76,11 @@ class SlaveActivity : BaseActivity() {
val smallSize = usable / 9 val smallSize = usable / 9
val largeSize = (usable - smallSize * 6) / 2 val largeSize = (usable - smallSize * 6) / 2
val rvHeight = smallSize * 3 + 3 * 4.dp val rvHeight = smallSize * 3 + 3 * 4.dp
binding.rvScaleList.layoutParams = binding.rvScaleList.layoutParams.also { it.height = rvHeight } binding.rvScaleList.updateLayoutParams<LinearLayout.LayoutParams> {
height = rvHeight
weight = 0f
topMargin = 20.dp
}
binding.rvScaleList.layoutManager = FlexboxLayoutManager(this).apply { binding.rvScaleList.layoutManager = FlexboxLayoutManager(this).apply {
flexDirection = FlexDirection.COLUMN flexDirection = FlexDirection.COLUMN
flexWrap = FlexWrap.WRAP flexWrap = FlexWrap.WRAP
@@ -86,6 +92,7 @@ class SlaveActivity : BaseActivity() {
binding.rvScaleList.adapter = scale22Adapter binding.rvScaleList.adapter = scale22Adapter
} }
ScaleDeviceConfig.DEVICE_ID_18 -> { ScaleDeviceConfig.DEVICE_ID_18 -> {
binding.rvScaleList.updateLayoutParams<LinearLayout.LayoutParams> { topMargin = 0 }
binding.rvScaleList.layoutManager = GridLayoutManager(this, 6).apply { binding.rvScaleList.layoutManager = GridLayoutManager(this, 6).apply {
spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int) = 1 override fun getSpanSize(position: Int) = 1
@@ -97,6 +104,7 @@ class SlaveActivity : BaseActivity() {
binding.rvScaleList.adapter = scale18Adapter binding.rvScaleList.adapter = scale18Adapter
} }
else -> { else -> {
binding.rvScaleList.updateLayoutParams<LinearLayout.LayoutParams> { topMargin = 20.dp }
binding.rvScaleList.layoutManager = LinearLayoutManager(this) binding.rvScaleList.layoutManager = LinearLayoutManager(this)
linearAdapter.setOnItemClickListener { _, _, position -> linearAdapter.setOnItemClickListener { _, _, position ->
val item = linearAdapter.items.getOrNull(position) ?: return@setOnItemClickListener val item = linearAdapter.items.getOrNull(position) ?: return@setOnItemClickListener
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

@@ -21,8 +21,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="30dp" android:layout_marginStart="30dp"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingTop="30dp"
android:paddingBottom="30dp"
android:textColor="@color/black" android:textColor="@color/black"
android:textSize="28sp" android:textSize="28sp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:background="@color/white">
<!-- 食材照片,权重占满剩余空间 -->
<ImageView
android:id="@+id/ivFoodPhoto"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scaleType="centerCrop"
tools:ignore="ContentDescription"
tools:src="@color/bg_color" />
<!-- 识别到的食材列表,无数据时隐藏 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:maxHeight="200dp"
android:nestedScrollingEnabled="false"
android:overScrollMode="never"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
tools:itemCount="4"
tools:listitem="@layout/list_item_search_goods_info"
tools:visibility="visible" />
<!-- 选中的食材名称 -->
<TextView
android:id="@+id/tvSelectedFood"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_marginTop="12dp"
android:gravity="center"
android:text="-"
android:textColor="@color/black333"
android:textSize="32sp" />
<!-- 秤1重量 -->
<TextView
android:id="@+id/tvWeight"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_marginTop="8dp"
android:background="@drawable/shape_white_12_corners"
android:gravity="center"
android:text="0.0 g"
android:textColor="@color/black333"
android:textSize="32sp" />
<!-- 更换食材 -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnChangeFood"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_marginTop="30dp"
android:background="@drawable/shape_green_bg"
android:text="更换食材"
android:textColor="@color/white"
android:textSize="32sp"
android:textStyle="bold" />
<!-- 取消 -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnCancel"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"
android:background="@drawable/shape_white_12_corners"
android:text="取消"
android:textColor="@color/black333"
android:textSize="32sp"
android:textStyle="bold" />
</LinearLayout>
+21 -17
View File
@@ -4,43 +4,47 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:padding="12dp" android:paddingHorizontal="5dp"
tools:background="@color/bg_color"> tools:background="@color/bg_color">
<!-- IP 与主设备状态同行显示 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<!-- 本机IP地址 --> <!-- 本机IP地址 -->
<TextView <TextView
android:id="@+id/tvDeviceIp" android:id="@+id/tvDeviceIp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:textSize="20sp"
android:layout_marginTop="0dp"
android:textSize="22sp"
android:textStyle="bold" android:textStyle="bold"
android:textColor="@color/home_title" android:textColor="@color/home_title"
tools:text="IP192.168.1.100" /> tools:text="IP192.168.1.100" />
<!-- 主设备连接状态 -->
<TextView
android:id="@+id/tvMasterStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textSize="16sp"
tools:text="主设备:未连接" />
</LinearLayout>
<!-- 设备信息 --> <!-- 设备信息 -->
<TextView <TextView
android:id="@+id/tvDeviceId" android:id="@+id/tvDeviceId"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="0dp" android:textSize="16sp"
android:textSize="18sp"
android:textColor="@color/home_sub_title" android:textColor="@color/home_sub_title"
tools:text="设备:device_02" /> tools:text="设备:device_02" />
<!-- 主设备连接状态 -->
<TextView
android:id="@+id/tvMasterStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="0dp"
android:layout_marginBottom="12dp"
android:textSize="16sp"
tools:text="主设备:未连接" />
<!-- 本机秤数据列表 --> <!-- 本机秤数据列表 -->
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvScaleList" android:id="@+id/rvScaleList"
@@ -46,11 +46,22 @@
<ImageView <ImageView
android:id="@+id/ivOperateIcon" android:id="@+id/ivOperateIcon"
android:layout_width="60dp" android:layout_width="80dp"
android:layout_height="60dp" android:layout_height="60dp"
android:layout_marginEnd="30dp"
tools:src="@drawable/ic_dish_selected" tools:src="@drawable/ic_dish_selected"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/ivClearIcon"
android:layout_marginEnd="10dp"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/ivClearIcon"
android:layout_width="80dp"
android:layout_height="60dp"
tools:src="@drawable/ic_dish_clear"
android:layout_marginEnd="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />