一个使用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地址

相关推荐
西瓜太郎123411 小时前
外层模型卡片与分组详情成功率不一致,应该怎么排查?
前端·typescript·go·软件工程·react
GreenTea11 小时前
vLLM 与 SGLang KV Cache 底层实现机制深度调研报告
前端·后端·算法
几何心凉14 小时前
没有万能模型:我用 AiiOnly Token Plan,把多款大模型的长处拼进同一个项目
前端
kyriewen14 小时前
Claude Code 的额度今天缩水了17%——官方公告上写的是"永久提高25%"
前端·ai编程·claude
雪芽蓝域zzs15 小时前
vue解构平铺VS对象包裹
前端·javascript·vue.js
风骏时光牛马15 小时前
从零到实战,完整AI学习路线
前端
三十而立洋16 小时前
深入理解 Monorepo:子包安装依赖
前端·前端工程化
IT_陈寒16 小时前
Java Stream处理大集合,我的内存怎么就炸了
前端·人工智能·后端
Captaincc16 小时前
AI 用量桌面端-桌面宠物自定义指南
前端·人工智能
OpenTiny社区17 小时前
码力全开,智启前端新生态|OpenTiny 登陆华为全联接大会2026
前端·github