refactor(dialog): 重构 CommonDialog 为链式调用 API,内置 title/content,全量替换旧调用方

This commit is contained in:
2026-04-16 15:02:33 +08:00
parent c3f3b1215b
commit ad63639f66
12 changed files with 196 additions and 208 deletions
@@ -0,0 +1,42 @@
package com.shuwei.dish.match.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.shuwei.dish.match.databinding.ListItemScaleRowBinding
import com.shuwei.dish.match.utils.WeightUtil
/**
* 线性列表秤数据 Adapter
* 用于 SlaveActivity 非22/18格子设备的秤列表展示
*/
class ScaleRowAdapter : BaseQuickAdapter<ScaleRowAdapter.ScaleItem, ScaleRowAdapter.VH>() {
/**
* 秤数据条目
* @param address 秤地址
* @param weight 重量(克)
* @param state 状态码
*/
data class ScaleItem(val address: Int, val weight: Double, val state: Int)
inner class VH(val b: ListItemScaleRowBinding) : QuickViewHolder(b.root)
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
return VH(ListItemScaleRowBinding.inflate(LayoutInflater.from(context), parent, false))
}
override fun onBindViewHolder(holder: VH, position: Int, item: ScaleItem?) {
item ?: return
holder.b.tvScaleLabel.text = "${item.address}"
holder.b.tvWeight.text = "${item.weight} g"
holder.b.tvState.text = when (item.state) {
WeightUtil.STATE_STABLE -> "稳定"
WeightUtil.STATE_UNSTABLE -> "不稳定"
WeightUtil.STATE_OVER_WEIGHT -> "超量"
else -> "${item.state}"
}
}
}
@@ -7,9 +7,7 @@ import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.View
import android.view.Window
import android.view.WindowManager
import androidx.annotation.StyleRes
import androidx.fragment.app.FragmentActivity
import com.shuwei.dish.match.databinding.DialogCommonBinding
import com.shuwei.dish.match.utils.ext.dp
import java.lang.ref.WeakReference
@@ -20,53 +18,69 @@ open class CommonDialog(
private lateinit var binding: DialogCommonBinding
private var titleText: String? = null
private var contentText: String? = null
private var negativeText = "取消"
private var positiveText = "确认"
private var negativeClick: (() -> Unit)? = null
private var positiveClick: (() -> Unit)? = null
private var dismissCallback: (() -> Unit)? = null
/** 设置标题,为空时隐藏 */
fun setTitle(text: String): CommonDialog = apply { titleText = text }
/** 设置内容,为空时隐藏 */
fun setContent(text: String): CommonDialog = apply { contentText = text }
/** 设置左侧取消按钮文字及点击回调 */
fun setNegativeButton(text: String, onClick: (() -> Unit)? = null): CommonDialog = apply {
negativeText = text
negativeClick = onClick
}
/** 设置右侧确认按钮文字及点击回调 */
fun setPositiveButton(text: String, onClick: (() -> Unit)? = null): CommonDialog = apply {
positiveText = text
positiveClick = onClick
}
/** 设置弹窗消失回调 */
fun setOnDismissCallback(callback: () -> Unit): CommonDialog = apply {
dismissCallback = callback
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
binding = DialogCommonBinding.inflate(layoutInflater)
setContentView(binding.root)
window?.run {
// decorView.setPadding(0.dp, 0, 0.dp, 0)
attributes = attributes.apply {
width = 708.dp
width = 660.dp
}
setBackgroundDrawable(ColorDrawable())
setCancelable(false)
// setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// )
}
binding.llContent.run {
removeAllViews()
addView(messageView)
binding.btnLeft.setOnClickListener {
negativeClick?.invoke()
dismiss()
}
addListener()
binding.btnRight.setOnClickListener {
positiveClick?.invoke()
dismiss()
}
setOnDismissListener { dismissCallback?.invoke() }
}
private fun addListener() {
binding.btnLeft.setOnClickListener { onLeftClick?.invoke() }
binding.btnRight.setOnClickListener { onRightClick?.invoke() }
setOnDismissListener { onDismiss?.invoke() }
}
override fun show() {
super.show()
binding.btnLeft.text = leftText
binding.btnRight.text = rightText
binding.tvTitle.text = titleText
binding.tvContent.text = contentText
binding.tvTitle.visibility = if (titleText.isNullOrEmpty()) View.GONE else View.VISIBLE
binding.tvContent.visibility = if (contentText.isNullOrEmpty()) View.GONE else View.VISIBLE
binding.btnLeft.text = negativeText
binding.btnRight.text = positiveText
}
var messageView: View? = null
var onLeftClick: (() -> Unit)? = null
var onRightClick: (() -> Unit)? = null
var leftText = ""
var rightText = ""
var onDismiss: (() -> Unit)? = null
}
open class SafeDialog(activity: Activity, @StyleRes themeResId: Int) :
@@ -1,38 +0,0 @@
package com.shuwei.dish.match.dialog
import android.content.Context
import android.view.LayoutInflater
import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
object DialogTool {
fun load(
context: Context,
title:String,
content:String,
leftBtnText: String,
rightBtnText: String,
leftBtnClick: () -> Unit = {},
rightBtnClick: () -> Unit = {}
) {
val layoutInflater = LayoutInflater.from(context)
val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
remindBinding.tvDialogTitle.text = title
remindBinding.tvDialogContent.text = content
CommonDialog(context).apply {
messageView = remindBinding.root
leftText = leftBtnText
rightText = rightBtnText
onLeftClick = {
leftBtnClick()
dismiss()
}
onRightClick = {
rightBtnClick()
dismiss()
}
onDismiss = { }
}.show()
}
}
@@ -15,7 +15,6 @@ import androidx.core.view.forEach
import androidx.lifecycle.ViewModelProvider
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.entity.SeasoningEntity
@@ -169,21 +168,13 @@ class DeviceConfigActivity : BaseActivity() {
val detector = MultiClickDetector(targetCount = 10, intervalMs = 800)
private fun defaultDataSettingDialog() {
val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
remindBinding.tvDialogTitle.text = "温馨提示"
remindBinding.tvDialogContent.text =
"您好,使用默认配置作为您的调料数据,则已有配置将被清除,确认吗?"
CommonDialog(this).apply {
messageView = remindBinding.root
leftText = "取消"
rightText = "确认"
onLeftClick = { dismiss() }
onRightClick = {
dismiss()
resetList()
}
onDismiss = { hideStatusBar() }
}.show()
CommonDialog(this)
.setTitle("温馨提示")
.setContent("您好,使用默认配置作为您的调料数据,则已有配置将被清除,确认吗?")
.setNegativeButton("取消")
.setPositiveButton("确认") { resetList() }
.setOnDismissCallback { hideStatusBar() }
.show()
}
private fun resetList() {
@@ -15,7 +15,6 @@ import com.shuwei.dish.match.adapter.DishPartAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivityDishSamplingBinding
import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.dialog.FoodSearchDialog
import com.shuwei.dish.match.dialog.CommonDialog
@@ -130,23 +129,18 @@ class DishSamplingActivity : BaseActivity() {
}
private fun saveDataRemindDialog() {
val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
remindBinding.tvDialogTitle.text = "温馨提示"
remindBinding.tvDialogContent.text = "您好,当前页面存在未保存的数据,确认返回吗?"
CommonDialog(this).apply {
messageView = remindBinding.root
leftText = "取消"
rightText = "确认"
onLeftClick = { dismiss() }
onRightClick = {
dismiss()
CommonDialog(this)
.setTitle("温馨提示")
.setContent("您好,当前页面存在未保存的数据,确认返回吗?")
.setNegativeButton("取消")
.setPositiveButton("确认") {
if (pageFrom == HOME) {
startActivity<SamplingListActivity>()
}
finish()
}
onDismiss = { hideStatusBar() }
}.show()
.setOnDismissCallback { hideStatusBar() }
.show()
}
@@ -21,6 +21,7 @@ import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.Scale18GridAdapter
import com.shuwei.dish.match.adapter.Scale22GridAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.databinding.ActivityMasterScaleBinding
import com.shuwei.dish.match.databinding.ListTypeScale1Binding
import com.shuwei.dish.match.databinding.ListTypeScale18Binding
@@ -402,14 +403,14 @@ class MasterScaleActivity : BaseActivity() {
* @param address 目标秤地址
*/
private fun showTareDialog(deviceId: String, ip: String, address: Int) {
android.app.AlertDialog.Builder(this)
CommonDialog(this)
.setTitle("清零确认")
.setMessage("设备 IP${ip.ifEmpty { "未知" }}\n确认对秤 $address 执行清零操作?")
.setPositiveButton("确认") { _, _ ->
.setContent("设备 IP${ip.ifEmpty { "未知" }}\n确认对秤 $address 执行清零操作?")
.setNegativeButton("取消")
.setPositiveButton("确认") {
val sent = ScaleServiceManager.sendTare(deviceId, address)
if (!sent) toast("设备未连接,清零失败")
}
.setNegativeButton("取消", null)
.show()
}
@@ -11,7 +11,6 @@ import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.DishPartAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.ActivityPrepareCookBinding
import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.dialog.FoodRecognizeDialog
import com.shuwei.dish.match.dialog.FoodSearchDialog
@@ -239,18 +238,12 @@ class PrepareCookActivity : BaseActivity() {
}
private fun showRemindDialog() {
val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
CommonDialog(this).apply {
messageView = remindBinding.root
leftText = "返回调整"
rightText = "确认无误"
onLeftClick = { dismiss() }
onRightClick = {
openSubmitPage()
dismiss()
}
onDismiss = { hideStatusBar() }
}.show()
CommonDialog(this)
.setTitle("温馨提示")
.setNegativeButton("返回调整")
.setPositiveButton("确认无误") { openSubmitPage() }
.setOnDismissCallback { hideStatusBar() }
.show()
}
@@ -431,20 +424,13 @@ class PrepareCookActivity : BaseActivity() {
* 未保存数据提醒
*/
private fun saveDataRemindDialog() {
val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
remindBinding.tvDialogTitle.text = "温馨提示"
remindBinding.tvDialogContent.text = "您好,当前页面存在尚未保存的数据,确认返回上页吗?"
CommonDialog(this).apply {
messageView = remindBinding.root
leftText = "取消"
rightText = "确认"
onLeftClick = { dismiss() }
onRightClick = {
dismiss()
finish()
}
onDismiss = { hideStatusBar() }
}.show()
CommonDialog(this)
.setTitle("温馨提示")
.setContent("您好,当前页面存在尚未保存的数据,确认返回吗?")
.setNegativeButton("取消")
.setPositiveButton("确认") { finish() }
.setOnDismissCallback { hideStatusBar() }
.show()
}
/**
@@ -15,7 +15,7 @@ import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivitySamplingBinding
import com.shuwei.dish.match.databinding.LayoutEmptyViewBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.dialog.DialogTool
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.utils.DateTimeUtil
@@ -378,16 +378,12 @@ class SamplingListActivity : BaseActivity() {
}
private fun showDeviceConfigDialog() {
DialogTool.load(
context = this,
title = "温馨提示",
content = "请先在设备配置页面进行调料设置",
leftBtnText = "取消",
rightBtnText = "去设置",
leftBtnClick = {},
rightBtnClick = {
startActivity<SettingActivity>()
})
CommonDialog(this)
.setTitle("温馨提示")
.setContent("请先在设备配置页面进行调料设置")
.setNegativeButton("取消")
.setPositiveButton("去设置") { startActivity<SettingActivity>() }
.show()
}
private var isVisible = false
@@ -9,7 +9,7 @@ import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivitySelectDishBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.dialog.DialogTool
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.ui.fragment.DishListFragment
@@ -95,17 +95,12 @@ class SelectDishActivity : BaseActivity() {
}
private fun showDeviceConfigDialog() {
DialogTool.load(
context = this,
title = "温馨提示",
content = "请先在设备配置页面进行调料设置",
leftBtnText = "取消",
rightBtnText = "去设置",
leftBtnClick = {},
rightBtnClick = {
startActivity<SettingActivity>()
}
)
CommonDialog(this)
.setTitle("温馨提示")
.setContent("请先在设备配置页面进行调料设置")
.setNegativeButton("取消")
.setPositiveButton("去设置") { startActivity<SettingActivity>() }
.show()
}
fun addViewListener() {
@@ -2,11 +2,8 @@ package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.activity.addCallback
import com.google.android.flexbox.AlignItems
import com.google.android.flexbox.FlexDirection
@@ -14,10 +11,11 @@ import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager
import com.shuwei.dish.match.adapter.Scale18GridAdapter
import com.shuwei.dish.match.adapter.Scale22GridAdapter
import com.shuwei.dish.match.adapter.ScaleRowAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.GlobalData
import com.shuwei.dish.match.databinding.ActivitySlaveBinding
import com.shuwei.dish.match.databinding.ListItemScaleRowBinding
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.scale.ScaleData
import com.shuwei.dish.match.scale.ScaleDeviceConfig
import com.shuwei.dish.match.scale.ScaleServiceManager
@@ -34,11 +32,8 @@ class SlaveActivity : BaseActivity() {
private lateinit var binding: ActivitySlaveBinding
/** 本机秤数据列表:address → (weight, state)线性列表模式使用 */
private data class ScaleItem(val address: Int, val weight: Double, val state: Int)
private val scaleList = mutableListOf<ScaleItem>()
private val linearAdapter = ScaleAdapter(scaleList)
/** 本机秤数据列表:线性列表模式使用 */
private val linearAdapter = ScaleRowAdapter()
/** 22个秤网格 adapter */
private var scale22Adapter: Scale22GridAdapter? = null
@@ -85,7 +80,9 @@ class SlaveActivity : BaseActivity() {
flexWrap = FlexWrap.WRAP
alignItems = AlignItems.FLEX_START
}
scale22Adapter = Scale22GridAdapter(largeSize, smallSize)
scale22Adapter = Scale22GridAdapter(largeSize, smallSize).also {
it.onItemClick = { scale -> showTareDialog(scale.address) }
}
binding.rvScaleList.adapter = scale22Adapter
}
ScaleDeviceConfig.DEVICE_ID_18 -> {
@@ -94,11 +91,17 @@ class SlaveActivity : BaseActivity() {
override fun getSpanSize(position: Int) = 1
}
}
scale18Adapter = Scale18GridAdapter()
scale18Adapter = Scale18GridAdapter().also {
it.onItemClick = { scale -> showTareDialog(scale.address) }
}
binding.rvScaleList.adapter = scale18Adapter
}
else -> {
binding.rvScaleList.layoutManager = LinearLayoutManager(this)
linearAdapter.setOnItemClickListener { _, _, position ->
val item = linearAdapter.items.getOrNull(position) ?: return@setOnItemClickListener
showTareDialog(item.address)
}
binding.rvScaleList.adapter = linearAdapter
}
}
@@ -144,16 +147,16 @@ class SlaveActivity : BaseActivity() {
scale18Adapter!!.updateByAddress(existing)
}
else -> {
val idx = scaleList.indexOfFirst { it.address == address }
val item = ScaleItem(address, weight, state)
val item = ScaleRowAdapter.ScaleItem(address, weight, state)
val list = linearAdapter.items.toMutableList()
val idx = list.indexOfFirst { it.address == address }
if (idx >= 0) {
scaleList[idx] = item
linearAdapter.notifyItemChanged(idx)
list[idx] = item
} else {
scaleList.add(item)
scaleList.sortBy { it.address }
linearAdapter.notifyDataSetChanged()
list.add(item)
list.sortBy { it.address }
}
linearAdapter.submitList(list)
}
}
}
@@ -182,6 +185,21 @@ class SlaveActivity : BaseActivity() {
const val TAG = "SlaveActivity"
}
/**
* 弹出清零确认对话框
* @param address 目标秤地址
*/
private fun showTareDialog(address: Int) {
CommonDialog(this)
.setTitle("清零确认")
.setContent("确认对秤 $address 执行清零操作?")
.setNegativeButton("取消")
.setPositiveButton("确认") {
WeightUtil.tareTwo(address)
}
.show()
}
/**
* 获取本机局域网 IP,委托给 NetworkUtil 统一处理版本兼容
*/
@@ -189,30 +207,5 @@ class SlaveActivity : BaseActivity() {
return NetworkUtil.getLocalIpAddress(this).ifEmpty { "未知" }
}
private class ScaleAdapter(private val data: List<ScaleItem>) :
RecyclerView.Adapter<ScaleAdapter.VH>() {
inner class VH(val binding: ListItemScaleRowBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = VH(
ListItemScaleRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
override fun getItemCount() = data.size
override fun onBindViewHolder(holder: VH, position: Int) {
val item = data[position]
val stateStr = when (item.state) {
WeightUtil.STATE_STABLE -> "稳定"
WeightUtil.STATE_UNSTABLE -> "不稳定"
WeightUtil.STATE_OVER_WEIGHT -> "超量"
else -> "${item.state}"
}
holder.binding.tvScaleLabel.text = "${item.address}"
holder.binding.tvWeight.text = "${item.weight} g"
holder.binding.tvState.text = stateStr
}
}
}
@@ -20,7 +20,6 @@ import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.base.BaseFragment
import com.shuwei.dish.match.databinding.FragmentDeviceConfigBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.dialog.SeasoningSearchDialog
import com.shuwei.dish.match.entity.SeasoningEntity
import com.shuwei.dish.match.entity.ResetReasoningRecord
@@ -39,7 +38,6 @@ import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible
import com.shuwei.dish.match.viewmodel.AppViewModel
import com.shuwei.dish.match.viewmodel.factory.AppFactory
import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
import com.shuwei.dish.match.ui.SamplingListActivity
import com.shuwei.dish.match.ui.SelectDishActivity
import com.shuwei.dish.match.utils.SpTool
+26 -10
View File
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
@@ -8,10 +7,29 @@
android:background="@drawable/shape_white_30_corners"
android:orientation="vertical">
<FrameLayout
android:id="@+id/llContent"
<TextView
android:id="@+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginTop="55dp"
android:layout_marginEnd="40dp"
android:gravity="center"
android:textColor="@color/black"
android:textSize="36sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="40dp"
android:layout_marginBottom="55dp"
android:gravity="center"
android:textColor="@color/black999"
android:textSize="26sp" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
@@ -20,7 +38,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_height="100dp"
android:gravity="center_vertical"
android:orientation="horizontal">
@@ -32,8 +50,7 @@
android:gravity="center"
android:background="@drawable/ripple_effect_light2"
android:textColor="@color/dish_green"
android:textSize="30sp"
tools:text="取消" />
android:textSize="30sp" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="1dp"
@@ -49,8 +66,7 @@
android:textColor="@color/dish_green"
android:background="@drawable/ripple_effect_light2"
android:textSize="30sp"
android:textStyle="bold"
tools:text="确定" />
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>