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

相关推荐
兆子龙2 小时前
从微信小程序 data-id 到 React 列表性能优化:少用闭包,多用 data-*
前端
滕青山2 小时前
文本行过滤/筛选 在线工具核心JS实现
前端·javascript·vue.js
时光不负努力2 小时前
编程常用模式集合
前端·javascript·typescript
恋猫de小郭2 小时前
Apple 的 ANE 被挖掘,AI 硬件公开,宣传的 38 TOPS 居然是"数字游戏"?
前端·人工智能·ios
小岛前端2 小时前
Node.js 宣布重大调整,运行十年的规则要改了!
前端·node.js
OpenTiny社区2 小时前
OpenTiny NEXT-SDK 重磅发布:四步把你的前端应用变成智能应用
前端·javascript·ai编程
梦想CAD控件2 小时前
在线CAD开发包结构与功能说明
前端·javascript·vue.js
张拭心2 小时前
春节后,有些公司明确要求 AI 经验了
android·前端·人工智能
时光不负努力2 小时前
typescript常用的dom 元素类型
前端·typescript