上一篇文章:Android DialogFragment快速使用方法 - (jianshu.com)
前言
请先看上一篇文章,本篇文件紧接着上一篇的思路和框架,所有的操作还是在父类的BaseDialog
下进行
关于ViewBinding
注意!!!不要和DataBinding弄混了
官方文档:视图绑定 | Android 开发者 | Android Developers (google.cn)
先说点题外话,DialogFragment也可以使用ViewBinding作为布局
第一步
在BaseDialog
中添加一个泛型VB
继承ViewBinding
,添加父类通用的binding
变量和binding
泛型实例化的方法
abstract class BaseDialog : DialogFragment() {
//...省略其他代码
protected lateinit var binding: VB
@Suppress("UNCHECKED_CAST")
private fun initViewBinding(inflater: LayoutInflater, container: ViewGroup?): View? {
val type = javaClass.genericSuperclass
return if (type is ParameterizedType) {
try {
val clazz = type.actualTypeArguments[0] as Class
val method = clazz.getMethod("inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.java)
binding = method.invoke(null, inflater, container, false) as VB
binding.root
} catch (e: Exception) {
throw RuntimeException(e)
}
} else {
null
}
}
}
这一波操作结束之后,子类的binding
都可以直接调用获取相应的View
第二步
和之前一样重写onCreateView
方法,只不过这里的的返回值需要改成第一步中的initViewBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return initViewBinding(inflater, container)
}
至此,ViewBinding就可用在DialogFragment上了
解决LightStatusBar的问题
LightStatusBar
(以下简称亮色模式)属性在DialogFragment
中一直是让我头疼的,主要是项目需求非常涣散,你根本不知道甲方会派一个什么外行来设计需求或者UI,有些时候弹窗是有背景蒙层的(就是背景自带的半透明黑,以下简称Dim
),有些时候又不需要蒙层,反正UI也是想一出是一出,完全没有标准的设计方案。
在DialogFragment中就更令人烦躁,当Dim
设置为0,且Activity
开启亮色模式时,你会惊奇的发现状态栏不见了,其实是白色状态栏和白色的状态栏字体融合了。
有些人这个时候会将Dialog
宽高设置成MATCH_PARENT
,那么问题又来了,点击外部取消弹窗失效。
在网上找了很久还是没有直接有效的方法,干脆自己琢磨,最终找到一个比较可行的方案:重写onCreateDialog
方法
abstract fun setDialogDim(): Float //用来设置Dim透明度 0f ~ 1f
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return if (setDialogDim() <= 0.1f) {
Dialog(requireContext(), R.style.DialogTheme)
} else {
super.onCreateDialog(savedInstanceState)
}
}
当Dim
小于0.1时禁用Dim
,这个时候就可以设置亮色模式了,当Dim
有值时,状态栏本身就是白色字体,不影响界面显示,下面是Theme
注意,Theme
这里的parent
属性,可以设置成任何一个Dialog
,但是千万不要使用Dialog.Alert
,会导致Dialog
显示的位置有问题,暂时没有时间去挖源码
到此,解决一个烦人的小问题,如果有更好的方案,欢迎在评论区回复。