BaseDialogFragment 自定义大小位置对话框

BaseDialogFragment

BaseDialogFragment 自定义大小位置对话框

直接上代码

/**
 * 自定义全屏对话框
 */
abstract class BaseDialogFragment() : DialogFragment() {

    private lateinit var builder: Builder

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NO_TITLE, android.R.style.Theme_Light_NoTitleBar_Fullscreen)
    }

    override fun onStart() {
        super.onStart()
        builder = initBuilder()
        config()

    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return LayoutInflater.from(context).inflate(initLayout(), null)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        initView()
    }

    /**
     * 初始化View
     */
    abstract fun initView()

    /**
     * 设置显示位置
     */
    abstract fun initBuilder(): Builder

    abstract fun initLayout(): Int

    private fun config() {
        if (dialog != null) {
            val dm = DisplayMetrics();
            activity?.windowManager?.defaultDisplay?.getMetrics(dm);
            val attributes = dialog.window?.attributes;
            attributes?.gravity = builder.getGravity()
            // attributes?.gravity = (Gravity.TOP) or (Gravity.START)
            context?.let {
                attributes?.y = DisplayUtil.dip2px(context!!, builder.getOffsetY()) //具体头部距离
            }
            context?.let {
                attributes?.x = DisplayUtil.dip2px(context!!, builder.getOffsetX()) //具体头部距离
            }
            dialog.window?.attributes = attributes
            val screenType = getScreenType()
            if (screenType == 1) {
                //横屏适配
                val height = dm.heightPixels * builder.getPixelsY()
                val width = height * builder.getRadio()
                dialog.window
                    ?.setLayout(
                        (width.toInt()),
                        (height.toInt())
                    )
            } else {
                //竖屏适配
                val width = dm.widthPixels * builder.getPixelsX()
                val height = width / builder.getRadio()
                dialog.window
                    ?.setLayout(
                        (width.toInt()),
                        (height.toInt())
                    )
            }
        }
    }


    abstract class Builder {
        abstract fun setModel(modelX: Float = 250F, modelY: Float = 300F): Builder
        abstract fun seOffset(x: Float = 0F, y: Float = 0F): Builder
        abstract fun setGravity(vararg args: Int): Builder
        abstract fun getGravity(): Int
        abstract fun getPixelsY(): Float
        abstract fun getPixelsX(): Float
        abstract fun getOffsetX(): Float
        abstract fun getOffsetY(): Float
        abstract fun getRadio(): Float

        companion object {
            var top = Gravity.TOP
            var start = Gravity.START
            var center = Gravity.CENTER
            var bottom = Gravity.BOTTOM
        }
    }

    class BuilderImpl : Builder() {
        private var gravity = -1
        private var x = 0F
        private var y = 0F
        //默认模型:宽,高,自己可以修改
        private var modelX = 250F
        private var modelY = 310F
        //横屏模式下适配 y的最大宽度  自己可以修改
        private val defaultMY = 375F
        //竖屏模式下适配 x的最大宽度  自己可以修改
        private val defaultMX = 375F
        /**
         * 对话框模型
         * 横屏模式下 x 最大宽度375F 
         * 竖屏模式下 y 最大宽度375F
         * @param modelX 模型宽
         * @param modelY 模型高
         */
        override fun setModel(modelX: Float, modelY: Float): Builder {
            this.modelX = modelX
            this.modelY = modelY
            return this
        }

        /**
         * 设置偏移
         * @param x 边距
         * @param y 边距
         */
        override fun seOffset(x: Float, y: Float): Builder {
            this.x = x
            this.y = y
            return this
        }
        
        //模型宽高比
        override fun getRadio() = modelX / modelY

        /**
         * @param args  Gravity.CENTER,Gravity.START 等等
         * 设置显示位置  可以输入多个参数组合
         */
        override fun setGravity(vararg args: Int): Builder {
            var g = -1
            for (i in args) {
                g = if (g != -1) {
                    g or i
                } else {
                    i
                }
            }
            this.gravity = g
            return this
        }

        override fun getGravity(): Int {
            if (gravity == -1) {
                return Gravity.CENTER
            }
            return gravity
        }


        override fun getPixelsY() = modelY / defaultMY
        override fun getPixelsX() = modelX / defaultMX

        override fun getOffsetX() = x
        override fun getOffsetY() = y

        companion object {
            fun build(): Builder {
                return BuilderImpl()
            }
        }
    }
    //获取屏幕方向
    private fun getScreenType(): Int {
        var type = 1
        val mConfiguration = this.resources.configuration; //获取设置的配置信息
        val ori = mConfiguration.orientation //获取屏幕方向
        if (ori == Configuration.ORIENTATION_LANDSCAPE) {
            //横屏
            type = 1
        } else if (ori == Configuration.ORIENTATION_PORTRAIT) {
            //竖屏
            type = 2
        }
        return type
    }
    

}

如何使用

/**
 * 自定义 继承BaseDialogFragment
 */
class MyDialogImpl : BaseDialogFragment() {


    override fun initBuilder(): Builder {
        //默认居中显示 宽 250  高300
       // return BuilderImpl.build()

        //setModel 设置窗口大小 竖屏模式下最大宽度为 375
         return BuilderImpl
             .build()
             .setModel(375F,200F)
             .setGravity(Builder.bottom)
    }

    override fun initLayout(): Int {
        return R.layout.sample_my_fragment_dialog
    }

    override fun initView() {

    }

}
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //显示
        val dialog = MyDialogImpl()
        dialog.show(supportFragmentManager, "dilog")
    }
}

工具类

import android.content.Context

/**
 * dp,sp 和 px 转换的辅助类
 */
class DisplayUtil private constructor() {
    companion object {
        /**
         * 将px值转换为dip或dp值,保证尺寸大小不变
         * DisplayMetrics类中属性density
         */
        fun px2dip(context: Context, pxValue: Float): Int {
            val scale = context.resources.displayMetrics.density
            return (pxValue / scale + 0.5f).toInt()
        }

        /**
         * 将dip或dp值转换为px值,保证尺寸大小不变
         * DisplayMetrics类中属性density
         */
        fun dip2px(context: Context, dipValue: Float): Int {
            val scale = context.resources.displayMetrics.density
            return (dipValue * scale + 0.5f).toInt()
        }

        /**
         * 将px值转换为sp值,保证文字大小不变
         * DisplayMetrics类中属性scaledDensity
         */
        fun px2sp(context: Context, pxValue: Float): Int {
            val fontScale = context.resources.displayMetrics.scaledDensity
            return (pxValue / fontScale + 0.5f).toInt()
        }

        /**
         * 将sp值转换为px值,保证文字大小不变
         * DisplayMetrics类中属性scaledDensity
         */
        fun sp2px(context: Context, spValue: Float): Int {
            val fontScale = context.resources.displayMetrics.scaledDensity
            return (spValue * fontScale + 0.5f).toInt()
        }
    }

    init { /* cannot be instantiated */
        throw UnsupportedOperationException("cannot be instantiated")
    }
}

你可能感兴趣的:(android开发)