针对目前弹框的使用比较频繁,现在动手封装一个通用弹框的基类,使用ViewBinding +DialogFragment,希望能够帮到大家。
1.onCreate()方法中添加Style.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.BaseDialogStyle)
}
BaseDialogStyle代码如下(大家根据自己的需求进行修改):
<style name="BaseDialogStyle" parent="Theme.MaterialComponents.DayNight.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowTranslucentStatus">true</item><!-- 解决全屏时状态栏变黑 -->
<item name="android:backgroundDimEnabled">true</item> <!-- 是否允许背景模糊 -->
<item name="android:windowIsTranslucent">true</item> <!-- 是否半透明 -->
<item name="android:windowIsFloating">true</item> <!-- 是否浮现在activity之上 -->
<item name="android:windowContentOverlay">@null</item> <!-- 是否有遮盖 -->
<item name="android:backgroundDimAmount">0.6</item> <!-- 设置背景模糊的透明度-->
</style>
2. 弹框核心代码:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
dialog?.setCanceledOnTouchOutside(isOnTouchOutSide)
dialog?.setOnKeyListener { _, keyCode, _ -> !isOnBackPress && keyCode == KeyEvent.KEYCODE_BACK }
initBinding(container)
initData()
return viewBinding?.root
}
3. 在onStart()方法中可以动态设置宽高和透明度以及弹框的位置(上下左右),弹框动画大家可以根据需要自行添加:
override fun onStart() {
super.onStart()
setSite()
}
private fun setSite() {
val mWindow = dialog?.window
val mLayoutParams = mWindow?.attributes
mLayoutParams?.width = windowWidth
mLayoutParams?.height = windowHeight
mLayoutParams?.gravity = viewSite
mWindow?.attributes = mLayoutParams
mWindow?.setDimAmount(alpha)
}
4. 完整代码如下:
abstract class BaseDialog<V : ViewBinding> constructor(
private val isOnTouchOutSide: Boolean = true,
private val isOnBackPress: Boolean = true,
private val viewSite: Int = Gravity.CENTER,
private val windowWidth: Int = ViewGroup.LayoutParams.WRAP_CONTENT,
private val windowHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT,
private val alpha: Float = 0.6f
) : DialogFragment() {
protected val viewBinding: V?
get() = _binding!!
private var _binding: V? = null
protected abstract fun initData()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.BaseDialogStyle)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
dialog?.setCanceledOnTouchOutside(isOnTouchOutSide)
dialog?.setOnKeyListener { _, keyCode, _ -> !isOnBackPress && keyCode == KeyEvent.KEYCODE_BACK }
initBinding(container)
initData()
return viewBinding?.root
}
override fun onStart() {
super.onStart()
setSite()
}
private fun setSite() {
val mWindow = dialog?.window
val mLayoutParams = mWindow?.attributes
mLayoutParams?.width = windowWidth
mLayoutParams?.height = windowHeight
mLayoutParams?.gravity = viewSite
mWindow?.attributes = mLayoutParams
mWindow?.setDimAmount(alpha)
}
/**
* 初始化viewBinding
*/
private fun initBinding(container: ViewGroup?) {
val type = javaClass.genericSuperclass
val clazz = (type as ParameterizedType).actualTypeArguments[0] as Class<V>
val method = clazz.getMethod(
"inflate",
LayoutInflater::class.java,
ViewGroup::class.java,
Boolean::class.java
)
_binding = method.invoke(null, layoutInflater, container, false) as V
}
}
最后,希望对大家有所帮助,如果有不对的地方,欢迎大家指正。谢谢!