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")
}
}