自定义告警弹窗

This commit is contained in:
2026-04-29 15:11:28 +08:00
parent 827d85724e
commit 5004917d66
25 changed files with 985 additions and 9 deletions

View File

@@ -0,0 +1,255 @@
package com.example.defenseapplication.view
import android.app.Dialog
import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.LinearLayout
import android.widget.EditText
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import com.example.defenseapplication.R
class CustomDialogFragment : androidx.fragment.app.DialogFragment() {
data class Config(
val title: String,
val message: String = "",
val positiveText: String = "确定",
val negativeText: String? = "取消",
val cancelOnTouchOutside: Boolean = true,
val showInput: Boolean = false,
val inputHint: String = "",
val inputText: String = "",
val inputType: Int = InputType.TYPE_CLASS_TEXT
)
private var onPositiveClick: ((String) -> Unit)? = null
private var onNegativeClick: (() -> Unit)? = null
private lateinit var config: Config
fun setOnPositiveClick(block: (String) -> Unit): CustomDialogFragment = apply {
onPositiveClick = block
}
fun setOnNegativeClick(block: () -> Unit): CustomDialogFragment = apply {
onNegativeClick = block
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
config = Config(
title = requireArguments().getString(ARG_TITLE).orEmpty(),
message = requireArguments().getString(ARG_MESSAGE).orEmpty(),
positiveText = requireArguments().getString(ARG_POSITIVE_TEXT).orEmpty(),
negativeText = requireArguments().getString(ARG_NEGATIVE_TEXT),
cancelOnTouchOutside = requireArguments().getBoolean(ARG_CANCEL_ON_TOUCH_OUTSIDE),
showInput = requireArguments().getBoolean(ARG_SHOW_INPUT),
inputHint = requireArguments().getString(ARG_INPUT_HINT).orEmpty(),
inputText = requireArguments().getString(ARG_INPUT_TEXT).orEmpty(),
inputType = requireArguments().getInt(ARG_INPUT_TYPE)
)
isCancelable = config.cancelOnTouchOutside
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
setCanceledOnTouchOutside(config.cancelOnTouchOutside)
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.dialog_custom, container, false)
}
override fun onStart() {
super.onStart()
dialog?.window?.let { window ->
window.setLayout(
(resources.displayMetrics.widthPixels * 0.88f).toInt(),
WindowManager.LayoutParams.WRAP_CONTENT
)
window.setBackgroundDrawableResource(android.R.color.transparent)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val tvTitle = view.findViewById<TextView>(R.id.tv_title)
val tvMessage = view.findViewById<TextView>(R.id.tv_message)
val etInput = view.findViewById<EditText>(R.id.et_input)
val btnNegative = view.findViewById<TextView>(R.id.btn_negative)
val btnPositive = view.findViewById<TextView>(R.id.btn_positive)
val dividerCenter = view.findViewById<View>(R.id.v_divider_center)
tvTitle.text = config.title
tvMessage.text = config.message
tvMessage.visibility = if (config.message.isBlank()) View.GONE else View.VISIBLE
etInput.visibility = if (config.showInput) View.VISIBLE else View.GONE
etInput.hint = config.inputHint
etInput.setText(config.inputText)
etInput.inputType = config.inputType
btnPositive.text = config.positiveText
val hasNegative = !config.negativeText.isNullOrBlank()
btnNegative.visibility = if (hasNegative) View.VISIBLE else View.GONE
dividerCenter.visibility = if (hasNegative) View.VISIBLE else View.GONE
if (hasNegative) {
btnNegative.text = config.negativeText
} else {
btnPositive.layoutParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
btnNegative.setOnClickListener {
onNegativeClick?.invoke()
dismissAllowingStateLoss()
}
btnPositive.setOnClickListener {
onPositiveClick?.invoke(etInput.text?.toString().orEmpty())
dismissAllowingStateLoss()
}
}
companion object {
private const val ARG_TITLE = "arg_title"
private const val ARG_MESSAGE = "arg_message"
private const val ARG_POSITIVE_TEXT = "arg_positive_text"
private const val ARG_NEGATIVE_TEXT = "arg_negative_text"
private const val ARG_CANCEL_ON_TOUCH_OUTSIDE = "arg_cancel_on_touch_outside"
private const val ARG_SHOW_INPUT = "arg_show_input"
private const val ARG_INPUT_HINT = "arg_input_hint"
private const val ARG_INPUT_TEXT = "arg_input_text"
private const val ARG_INPUT_TYPE = "arg_input_type"
fun newInstance(config: Config): CustomDialogFragment {
return CustomDialogFragment().apply {
arguments = bundleOf(
ARG_TITLE to config.title,
ARG_MESSAGE to config.message,
ARG_POSITIVE_TEXT to config.positiveText,
ARG_NEGATIVE_TEXT to config.negativeText,
ARG_CANCEL_ON_TOUCH_OUTSIDE to config.cancelOnTouchOutside,
ARG_SHOW_INPUT to config.showInput,
ARG_INPUT_HINT to config.inputHint,
ARG_INPUT_TEXT to config.inputText,
ARG_INPUT_TYPE to config.inputType
)
}
}
}
}
object DefenseDialogs {
private const val DEFAULT_TAG = "custom_dialog_fragment"
fun showDialog(
activity: FragmentActivity,
config: CustomDialogFragment.Config,
tag: String = DEFAULT_TAG,
onPositiveClick: (String) -> Unit = {},
onNegativeClick: () -> Unit = {}
): CustomDialogFragment {
return CustomDialogFragment.newInstance(config)
.setOnPositiveClick(onPositiveClick)
.setOnNegativeClick(onNegativeClick)
.also { it.show(activity.supportFragmentManager, tag) }
}
fun showDialog(
fragment: Fragment,
config: CustomDialogFragment.Config,
tag: String = DEFAULT_TAG,
onPositiveClick: (String) -> Unit = {},
onNegativeClick: () -> Unit = {}
): CustomDialogFragment {
return CustomDialogFragment.newInstance(config)
.setOnPositiveClick(onPositiveClick)
.setOnNegativeClick(onNegativeClick)
.also { it.show(fragment.parentFragmentManager, tag) }
}
fun intrusionAlertConfig(deviceName: String, timeText: String): CustomDialogFragment.Config {
return CustomDialogFragment.Config(
title = "入侵告警",
message = "${timeText}有人入侵\n${deviceName}",
positiveText = "去看一下",
negativeText = "取消"
)
}
fun warmPromptConfig(deviceName: String, runDays: Int): CustomDialogFragment.Config {
return CustomDialogFragment.Config(
title = "温馨提示",
message = "${deviceName}】设备已经运行\n${runDays}天请及时维护",
positiveText = "知道了",
negativeText = null
)
}
fun deviceOfflineConfig(): CustomDialogFragment.Config {
return CustomDialogFragment.Config(
title = "设备离线",
message = "设备已离线请检查设备的WIF及电\n源情况",
positiveText = "知道了",
negativeText = null
)
}
fun strikeDistanceConfig(defaultDistance: String): CustomDialogFragment.Config {
return CustomDialogFragment.Config(
title = "打击距离",
message = "",
positiveText = "确定",
negativeText = "取消",
showInput = true,
inputHint = "请输入打击距离",
inputText = defaultDistance,
inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
)
}
}
fun FragmentActivity.showDefenseDialog(
config: CustomDialogFragment.Config,
tag: String = "custom_dialog_fragment",
onPositiveClick: (String) -> Unit = {},
onNegativeClick: () -> Unit = {}
): CustomDialogFragment {
return DefenseDialogs.showDialog(this, config, tag, onPositiveClick, onNegativeClick)
}
fun Fragment.showDefenseDialog(
config: CustomDialogFragment.Config,
tag: String = "custom_dialog_fragment",
onPositiveClick: (String) -> Unit = {},
onNegativeClick: () -> Unit = {}
): CustomDialogFragment {
return DefenseDialogs.showDialog(this, config, tag, onPositiveClick, onNegativeClick)
}
fun FragmentManager.showDefenseDialog(
config: CustomDialogFragment.Config,
tag: String = "custom_dialog_fragment",
onPositiveClick: (String) -> Unit = {},
onNegativeClick: () -> Unit = {}
): CustomDialogFragment {
return CustomDialogFragment.newInstance(config)
.setOnPositiveClick(onPositiveClick)
.setOnNegativeClick(onNegativeClick)
.also { it.show(this, tag) }
}