一个使用ViewBinding封装的Dialog

一个使用ViewBinding封装的Dialog,使用方便简单

话不多说,直接上干货

使用方法

kotlin 复制代码
showXDialog(DialogCustomBinding::inflate) {
    setCancelable(true)
    setCanceledOnTouchOutside(true)
    setDimAmount(0.7f)
    setWidth(300)
    setGravity(Gravity.CENTER)
    binding.apply {
        dialogButtonConfirm.setOnClickListener {
            toast("确定")
            dismiss()
        }
        dialogButtonCancel.setOnClickListener {
            toast("取消")
            dismiss()
        }
    }

}

实现方法

1、先封装一个 DialogScope
kotlin 复制代码
class DialogScope<VB : ViewBinding>(
    val dialog: Dialog,
    val binding: VB
) {

    private val window get() = dialog.window
    private val context get() = dialog.context

    private val params: WindowManager.LayoutParams?
        get() = window?.attributes

    /* ---------------- 基础 ---------------- */

    fun setCancelable(flag: Boolean) {
        dialog.setCancelable(flag)
    }

    fun setCanceledOnTouchOutside(flag: Boolean) {
        dialog.setCanceledOnTouchOutside(flag)
    }

    fun setDimAmount(amount: Float) {
        window?.setDimAmount(amount)
    }

    fun dismiss() {
        dialog.dismiss()
    }

    /* ---------------- 固定宽高 ---------------- */

    fun setWidth(widthDp: Int) {
        params?.let {
            it.width = widthDp.dp
            window?.attributes = it
        }
    }

    fun setHeight(heightDp: Int) {
        params?.let {
            it.height = heightDp.dp
            window?.attributes = it
        }
    }

    /* ---------------- 屏幕比例 ---------------- */

    fun setScreenWidthAspect(aspect: Float) {
        val screenWidth = context.resources.displayMetrics.widthPixels
        params?.let {
            it.width = (screenWidth * aspect).toInt()
            window?.attributes = it
        }
    }

    fun setScreenHeightAspect(aspect: Float) {
        val screenHeight = context.resources.displayMetrics.heightPixels
        params?.let {
            it.height = (screenHeight * aspect).toInt()
            window?.attributes = it
        }
    }

    /* ---------------- 重力 ---------------- */

    fun setGravity(gravity: Int) {
        params?.let {
            it.gravity = gravity
            window?.attributes = it
        }
    }
}

2、再封装Dialog

kotlin 复制代码
class XDialog<VB : ViewBinding>(
    private val inflater: (LayoutInflater) -> VB
) : DialogFragment() {

    private var _binding: VB? = null
    private val binding get() = _binding!!

    private var dslBlock: (DialogScope<VB>.() -> Unit)? = null

    fun setDsl(block: DialogScope<VB>.() -> Unit) {
        dslBlock = block
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return Dialog(requireContext()).apply {
            requestWindowFeature(Window.FEATURE_NO_TITLE) // 防止 requestFeature() 异常
        }
    }

    override fun onResume() {
        //去除左右边距
        dialog!!.window!!.decorView.setPadding(0, 0, 0, 0)
        super.onResume()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = this.inflater.invoke(inflater)
        return binding.root
    }

    override fun onStart() {
        super.onStart()
        dialog?.window?.let { window ->
            window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            // 先给一个默认值,防止 wrap_content 失效
            val params = window.attributes
            params.width = ViewGroup.LayoutParams.WRAP_CONTENT
            params.height = ViewGroup.LayoutParams.WRAP_CONTENT
            window.attributes = params
        }
        dialog?.let {
            dslBlock?.invoke(DialogScope(it, binding))
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}
如果有帮助到你,请点赞收藏
最后附上源码地址

Gitee地址

相关推荐
WILLF2 分钟前
前端视角:Python requests vs JS axios
前端·python
半个落月6 分钟前
在浏览器里运行 DeepSeek-R1:React 对话界面与安全渲染(三)
前端·人工智能·react.js
Synmbrf10 分钟前
micro-app 404 问题排查与修复
前端
西安栈上月明软件科技有限公司12 分钟前
GEO 友好度检测器技术实现(已开源)
前端
汉堡大王952717 分钟前
用 Trae Work 自动化任务,6 分钟生成一份前端生态周报
前端·javascript·人工智能
深圳佛手20 分钟前
安装DeepSeek Harness npx @deepseek-ai/dsh web 长时间没反应,安装失败,如何解决?
前端
Csvn33 分钟前
事件循环与渲染时机:一文吃透宏任务、微任务和 rAF
前端
章鱼小丸子逃跑中39 分钟前
【2025最新版】如何将fnm与node.js安装在D盘?【保姆级安装及人性话理解教程】
前端·javascript·npm·node.js
Larcher1 小时前
从 SDD 到可交付:我如何用规范驱动 AI 做出一个 Chrome 翻译插件
前端·后端·架构
suaizai_1 小时前
AI Agent如何懂你:四层能力拆解
java·前端·人工智能