假设我在一个名为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);

这样做的问题是,我必须记住将来在两个地方对宽度和高度进行任何更改。


当前回答

在我的例子中,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 }

其他回答

我最终覆盖Fragment.onResume()并从底层对话框中抓取属性,然后在那里设置宽度/高度参数。我将最外层的布局高度/宽度设置为match_parent。注意,这段代码似乎也尊重我在xml布局中定义的页边距。

@Override
public void onResume() {
    super.onResume();
    ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes();
    params.width = LayoutParams.MATCH_PARENT;
    params.height = LayoutParams.MATCH_PARENT;
    getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
}

你可以下面的代码设置布局的宽度和高度从java。

final AlertDialog alertDialog  = alertDialogBuilder.create();
final WindowManager.LayoutParams WMLP = alertDialog.getWindow().getAttributes();

WMLP.gravity = Gravity.TOP;
WMLP.y = mActionBarHeight;
WMLP.x = getResources().getDimensionPixelSize(R.dimen.unknown_image_width);

alertDialog.getWindow().setAttributes(WMLP);
alertDialog.show();

设置自定义对话框布局的父布局为RelativeLayout,自动获取公共宽度和高度。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

如果直接从资源值转换:

int width = getResources().getDimensionPixelSize(R.dimen.popup_width);
int height = getResources().getDimensionPixelSize(R.dimen.popup_height);        
getDialog().getWindow().setLayout(width, height);

然后在对话框的布局中指定match_parent:

android:layout_width="match_parent"
android:layout_height="match_parent"

现在你只需要担心一个地方(即你的DialogFragment)。onResume方法)。这并不完美,但至少它适用于将RelativeLayout作为对话框布局文件的根。

其他的答案都对我没用。对我来说,解决这个问题的方法是创建一种样式,你可以选择你想要对话框占据屏幕的百分比:

<style name="RelativeDialog" parent="android:style/Theme.Dialog">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="windowFixedWidthMajor">90%</item>
    <item name="windowFixedWidthMinor">90%</item>
    <item name="android:windowMinWidthMajor">90%</item>
    <item name="android:windowMinWidthMinor">90%</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowAnimationStyle">@android:style/Animation</item>
</style>

而不是像这样设置对话框的样式:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(STYLE_NO_TITLE, R.style.RelativeDialog)
}