假设我在一个名为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);
这样做的问题是,我必须记住将来在两个地方对宽度和高度进行任何更改。
要获得一个几乎覆盖整个屏幕的Dialog:首先定义一个ScreenParameter类
public class ScreenParameters
{
public static int Width;
public static int Height;
public ScreenParameters()
{
LayoutParams l = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
Width= l.width;
Height = l.height;
}
}
然后你必须在getDialog.getWindow().setLayout()方法之前调用screenparameter
@Override
public void onResume()
{
super.onResume();
ScreenParameters s = new ScreenParameters();
getDialog().getWindow().setLayout(s.Width , s.Height);
}
在我的例子中,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
}
Working on Android 6.0, ran into the same issue. AlertDialog would default to predefined width set in the theme regardless of the actual width set in the custom view's root Layout. I was able to get it to set properly adjusting the width of the loading_message TextView. Without investigating further, it seems that sizing the actual elements and having the root Layout wrap around them makes it work as expected. Below is an XML layout of a loading dialog which sets width of the the dialog correctly. Using the this library for the animation.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/custom_color"
android:padding="@dimen/custom_dimen">
<com.github.rahatarmanahmed.cpv.CircularProgressView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/progress_view"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerHorizontal="true"
app:cpv_color="@color/white"
app:cpv_animAutostart="true"
app:cpv_indeterminate="true" />
<TextView
android:id="@+id/loading_message"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_below="@+id/progress_view"
android:layout_centerHorizontal="true"
android:gravity="center"
android:textSize="18dp"
android:layout_marginTop="@dimen/custom_dimen"
android:textColor="@color/white"
android:text="@string/custom_string"/>
</RelativeLayout>
我把@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
)
}