假设我在一个名为my_dialog_fragment.xml的xml布局文件中指定了我的DialogFragment的布局,并且我将其根视图的layout_width和layout_height值指定为固定值(例如100dp)。然后我在我的DialogFragment的onCreateView(…)方法中膨胀这个布局,如下所示:
View view = inflater.inflate(R.layout.my_dialog_fragment, container, false);
可悲的是,我发现当我的DialogFragment出现时,它不尊重layout_width和layout_height值在其xml布局文件中指定,而是根据其内容收缩或展开。有人知道我是否或如何得到我的DialogFragment尊重layout_width和layout_height值指定在其xml布局文件?目前,我必须在我的DialogFragment的onResume()方法中再次指定对话框的宽度和高度,如下所示:
getDialog().getWindow().setLayout(width, height);
这样做的问题是,我必须记住将来在两个地方对宽度和高度进行任何更改。
我把@rmirabella的回答也更新了一下,让它也能处理身高问题:
private fun DialogFragment.setSize(widthPercentage: Int, heightPercentage: Int) {
val newWidth = widthPercentage.toFloat() / 100
val newHeight = heightPercentage.toFloat() / 100
val dm = Resources.getSystem().displayMetrics
val rect = dm.run { Rect(0, 0, widthPixels, heightPixels) }
val percentWidth = rect.width() * newWidth
val percentHeight = rect.height() * newHeight
dialog?.window?.setLayout(percentWidth.toInt(), percentHeight.toInt())
}
然后在你的DialogFragment中或onStart()之后:
override fun onStart() {
super.onStart()
setSize(
widthPercentage = 100,
heightPercentage = 80
)
}
在我的例子中,DialogFragment占用了完整的活动大小,就像一个Fragment一样。DialogFragment基于xml布局,而不是AlertDialog。我的错误在于将对话片段作为常规片段添加到FragmentManager中:
fragmentManager?.beginTransaction()?.run {
replace(R.id.container, MyDialogFragment.newInstance(), MyDialogFragment.TAG)
addToBackStack(MyDialogFragment.TAG)
}?.commitAllowingStateLoss()
相反,我需要显示对话片段:
val dialogFragment = MyDialogFragment.newInstance()
fragmentManager?.let { dialogFragment.show(it, MyDialogFragment.TAG) }
经过一些编辑(我在布局中有ViewPager2),对话框片段变得太窄:
我使用了N1hk的解决方案:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
dialog?.window?.attributes?.width = ViewGroup.LayoutParams.MATCH_PARENT
dialog?.window?.attributes?.height = ViewGroup.LayoutParams.MATCH_PARENT
}
现在它已经定义了宽度和高度,而不是完整的活动大小。
我想说onCreateView和onCreateDialog。如果你有一个基于布局的对话片段,你可以使用这两种方法中的任何一种。
If you use onCreateView, then you should use onActivityCreated to set width.
If you use onCreateDialog instead of onCreateView, you can set parameters there. onActivityCreated won't be needed.
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
super.onCreateDialog(savedInstanceState)
val view = activity?.layoutInflater?.inflate(R.layout.your_layout, null)
val dialogBuilder = MaterialAlertDialogBuilder(context!!).apply { // Or AlertDialog.Builder(context!!).apply
setView(view)
// setCancelable(false)
}
view.text_view.text = "Some text"
val dialog = dialogBuilder.create()
// You can access dialog.window here, if needed.
return dialog
}