package com.xw.common
|
|
import android.content.Context
|
import android.graphics.Color
|
import android.os.Handler
|
import android.os.Looper
|
import android.text.method.LinkMovementMethod
|
import android.util.TypedValue
|
import android.view.Gravity
|
import android.widget.Button
|
import androidx.appcompat.widget.AppCompatTextView
|
import androidx.core.content.ContextCompat
|
import androidx.core.view.isVisible
|
import androidx.databinding.DataBindingUtil
|
import com.afollestad.materialdialogs.LayoutMode
|
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
import com.afollestad.materialdialogs.callbacks.onDismiss
|
import com.afollestad.materialdialogs.customview.customView
|
import com.afollestad.materialdialogs.customview.getCustomView
|
import com.hjq.permissions.Permission
|
import com.hjq.permissions.XXPermissions
|
import com.xw.common.databinding.DialogShowSelectBinding
|
import java.util.WeakHashMap
|
|
object CommonDialog {
|
|
fun showLocationNotGrantedTipsDialog(context: Context) {
|
/*
|
CommonDialog.showSingleTipsDialog(
|
context,
|
"您未开启gps权限,无法获取当前定位,请打开后重新操作",
|
null
|
)
|
*/
|
|
// CommonDialog.showCommonTipsDialog(
|
CommonDialog.showSingleTipsDialog(
|
context = context,
|
content = "您未开启gps权限,无法获取当前定位,请打开后重新操作", // "定位权限已被拒绝,将无法获取当前位置,请前往系统设置开启定位权限。",
|
leftText = "取消",
|
rightText = "去设置",
|
// leftBlock = { dialog -> dialog.dismiss() },
|
rightBlock = { dialog ->
|
// 跳转到当前应用的权限设置页
|
XXPermissions.startPermissionActivity(
|
context,
|
arrayOf(Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_COARSE_LOCATION)
|
)
|
true
|
}
|
)
|
}
|
|
// 记录每个页面(Context)当前正在展示的"单例"提示弹窗,避免同一界面重复弹出相同弹窗。
|
// 用 WeakHashMap 以 Context 为 key,Activity 销毁后可被回收,不会内存泄漏。
|
private val singleTipsDialogMap = WeakHashMap<Context, MaterialDialog>()
|
|
/**
|
* 单例提示弹窗:同一个 Activity(Context) 内若已弹出且尚未取消,则不再重复弹出。
|
*
|
* 适用于定位/GPS 等可能被多处回调(多次 onLocationChanged 等)同时触发、
|
* 导致同一界面叠加出多个相同提示弹窗的场景。
|
*
|
* @param content 内容
|
* @param leftBlock 回调事件 返回true dismiss
|
* @param rightBlock 回调事件 返回true dismiss
|
*/
|
private fun showSingleTipsDialog(
|
context: Context,
|
content: String,
|
leftText: String? = null,
|
rightText: String? = "确定",
|
leftBlock: (MaterialDialog) -> Boolean = { true },
|
rightBlock: (MaterialDialog) -> Boolean = { true }
|
) {
|
Handler(Looper.getMainLooper()).post {
|
// 该界面已弹出同类弹窗且仍在显示,直接跳过,避免重复弹出
|
singleTipsDialogMap[context]?.let { if (it.isShowing) return@post }
|
|
val dialog = MaterialDialog(context).apply {
|
SecureScreenShot.apply(window)
|
customView(
|
R.layout.dialog_confirm, noVerticalPadding = true, dialogWrapContent = false
|
)
|
|
cancelable(true)
|
cornerRadius(15f)
|
|
val tvContent = findViewById<AppCompatTextView>(R.id.content)
|
val btnLeft = findViewById<Button>(R.id.btnLeft)
|
val btnRight = findViewById<Button>(R.id.btnRight)
|
tvContent.text = content
|
btnLeft.text = leftText ?: ""
|
btnRight.text = rightText ?: ""
|
btnLeft.isVisible = !leftText.isNullOrEmpty()
|
btnRight.isVisible = !rightText.isNullOrEmpty()
|
btnLeft.setOnClickListener { if (leftBlock(this)) dismiss() }
|
btnRight.setOnClickListener { if (rightBlock(this)) dismiss() }
|
// 弹窗被关闭后移除记录,下次可正常再次弹出
|
onDismiss { singleTipsDialogMap.remove(context) }
|
}
|
singleTipsDialogMap[context] = dialog
|
dialog.show()
|
dialog.window?.setGravity(Gravity.CENTER)
|
// dialog.window?.setWindowAnimations(R.style.AnimLeft)
|
}
|
}
|
|
/**
|
* 通用提示弹窗
|
* @param content 内容
|
* @param leftBlock 回调事件 返回true dismiss
|
* @param rightBlock 回调事件 返回true dismiss
|
*/
|
fun showTipsDialog(
|
context: Context,
|
content: String,
|
leftText: String? = "取消",
|
rightText: String? = "确定",
|
leftBlock: () -> Boolean = { true },
|
rightBlock: () -> Boolean = { true }
|
) {
|
showCommonTipsDialog(
|
context = context,
|
content = content,
|
leftText = leftText,
|
rightText = rightText,
|
leftBlock = { dialog ->
|
if (leftBlock.invoke()) {
|
dialog.dismiss()
|
}
|
},
|
rightBlock = { dialog ->
|
if (rightBlock.invoke()) {
|
dialog.dismiss()
|
}
|
},
|
)
|
}
|
|
/**
|
* 通用提示弹窗
|
* @param content 内容
|
* @param leftBlock 回调事件 返回true dismiss
|
* @param rightBlock 回调事件 返回true dismiss
|
*/
|
fun showCommonTipsDialog(
|
context: Context,
|
content: String,
|
leftText: String? = "取消",
|
rightText: String? = "确定",
|
cancelable: Boolean = true,
|
cancelOnTouchOutside: Boolean = true,
|
leftBlock: (MaterialDialog) -> Unit = { },
|
rightBlock: (MaterialDialog) -> Unit = { }
|
) {
|
Handler(Looper.getMainLooper()).post {
|
val dialog = MaterialDialog(context).apply {
|
SecureScreenShot.apply(window)
|
customView(
|
R.layout.dialog_confirm, noVerticalPadding = true, dialogWrapContent = false
|
)
|
|
cancelable(cancelable)
|
cancelOnTouchOutside(cancelOnTouchOutside)
|
cornerRadius(15f)
|
|
val tvContent = findViewById<AppCompatTextView>(R.id.content)
|
val btnLeft = findViewById<Button>(R.id.btnLeft)
|
val btnRight = findViewById<Button>(R.id.btnRight)
|
tvContent.text = content
|
btnLeft.text = leftText ?: ""
|
btnRight.text = rightText ?: ""
|
btnLeft.isVisible = !leftText.isNullOrEmpty()
|
btnRight.isVisible = !rightText.isNullOrEmpty()
|
btnLeft.setOnClickListener {
|
leftBlock(this)
|
}
|
btnRight.setOnClickListener {
|
rightBlock(this)
|
}
|
}
|
dialog.show()
|
dialog.window?.setGravity(Gravity.CENTER)
|
// dialog.window?.setWindowAnimations(R.style.AnimLeft)
|
}
|
}
|
|
fun showTypeDialog(context: Context, block: (Int) -> Unit) {
|
MaterialDialog(context, BottomSheet(LayoutMode.WRAP_CONTENT))
|
.cornerRadius(15f)
|
.cancelable(true)
|
.show {
|
SecureScreenShot.apply(window)
|
customView(
|
R.layout.dialog_show_select,
|
noVerticalPadding = true,
|
dialogWrapContent = false
|
)
|
DataBindingUtil.bind<DialogShowSelectBinding>(getCustomView())?.let { bind ->
|
bind.camera.setOnClickListener {
|
block(0)
|
dismiss()
|
}
|
bind.album.setOnClickListener {
|
block(1)
|
dismiss()
|
}
|
bind.cancel.setOnClickListener { dismiss() }
|
}
|
}
|
}
|
|
/**
|
* 通用提示弹窗
|
* @param cancelable 是否能够点击物理返回按钮取消
|
* @param cancelOnTouchOutside 是否能够点击空白区域取消
|
* @param title 标题
|
* @param titleTextSize 标题字号大小 单位SP
|
* @param titleTextColor 标题字体颜色资源id
|
* @param content 内容
|
* @param contentTextSize 内容字号大小 单位SP
|
* @param contentTextColor 内容字体颜色资源id
|
* @param leftOperationText 左边操作按钮文案
|
* @param leftOperationTextSize 左边操作按钮文案字体大小
|
* @param leftOperationTextColor 左边操作按钮文案字体颜色
|
* @param rightOperationText 右边操作按钮文案
|
* @param rightOperationTextSize 右边操作按钮文案字体大小
|
* @param rightOperationTextColor 右边操作按钮文案字体颜色
|
* @param leftOperationBlock 回调事件 返回true dismiss
|
* @param rightOperationBlock 回调事件 返回true dismiss
|
*/
|
fun showNoticeDialog(
|
context: Context,
|
cancelable: Boolean = true,
|
cancelOnTouchOutside: Boolean = true,
|
title: CharSequence,
|
titleTextSize: Float = 18f,
|
titleTextColor: Int = R.color.gray_10,
|
content: CharSequence,
|
contentTextSize: Float = 14f,
|
contentTextColor: Int = R.color.gray_9,
|
contentTextGravity: Int = Gravity.CENTER,
|
leftOperationText: String? = "取消",
|
leftOperationTextSize: Float = 16f,
|
leftOperationTextColor: Int = R.color.gray_10,
|
rightOperationText: String? = "确定",
|
rightOperationTextSize: Float = 16f,
|
rightOperationTextColor: Int = R.color.blue_5,
|
leftOperationBlock: () -> Boolean = { true },
|
rightOperationBlock: () -> Boolean = { true }
|
) {
|
Handler(Looper.getMainLooper()).post {
|
val dialog = MaterialDialog(context).apply {
|
SecureScreenShot.apply(window)
|
customView(
|
R.layout.dialog_notice, noVerticalPadding = true, dialogWrapContent = false
|
)
|
cancelable(cancelable)
|
cancelOnTouchOutside(cancelOnTouchOutside)
|
cornerRadius(5f)
|
|
val tvTitle = findViewById<AppCompatTextView>(R.id.title)
|
val tvContent = findViewById<AppCompatTextView>(R.id.content)
|
val btnLeft = findViewById<Button>(R.id.btnLeft)
|
val btnRight = findViewById<Button>(R.id.btnRight)
|
tvTitle.text = title
|
tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, titleTextSize)
|
tvTitle.setTextColor(ContextCompat.getColor(context, titleTextColor))
|
tvContent.text = content
|
tvContent.highlightColor = Color.TRANSPARENT
|
tvContent.movementMethod = LinkMovementMethod.getInstance()
|
tvContent.setTextSize(TypedValue.COMPLEX_UNIT_SP, contentTextSize)
|
tvContent.setTextColor(ContextCompat.getColor(context, contentTextColor))
|
tvContent.gravity = contentTextGravity
|
btnLeft.text = leftOperationText ?: ""
|
btnLeft.setTextSize(TypedValue.COMPLEX_UNIT_SP, leftOperationTextSize)
|
btnLeft.setTextColor(ContextCompat.getColor(context, leftOperationTextColor))
|
btnRight.text = rightOperationText ?: ""
|
btnRight.setTextSize(TypedValue.COMPLEX_UNIT_SP, rightOperationTextSize)
|
btnRight.setTextColor(ContextCompat.getColor(context, rightOperationTextColor))
|
btnLeft.isVisible = !leftOperationText.isNullOrEmpty()
|
btnRight.isVisible = !rightOperationText.isNullOrEmpty()
|
btnLeft.setOnClickListener {
|
if (leftOperationBlock()) {
|
dismiss()
|
}
|
}
|
btnRight.setOnClickListener {
|
if (rightOperationBlock()) {
|
dismiss()
|
}
|
}
|
}
|
dialog.show()
|
dialog.window?.setGravity(Gravity.CENTER)
|
// dialog.window?.setWindowAnimations(R.style.AnimLeft)
|
}
|
}
|
|
}
|