假设我在一个名为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定义以下在XML主布局(线性布局在我的情况下):

android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="1000dp"
android:minHeight="450dp"

如果直接从资源值转换:

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作为对话框布局文件的根。


你可以下面的代码设置布局的宽度和高度从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();

我修复了它设置根元素布局参数。

int width = activity.getResources().getDisplayMetrics().widthPixels;
int height = activity.getResources().getDisplayMetrics().heightPixels;
content.setLayoutParams(new LinearLayout.LayoutParams(width, height));

在我的案例中,唯一有效的是指向这里的解决方案:http://adilatwork.blogspot.mx/2012/11/android-dialogfragment-dialog-sizing.html

来自Adil博客文章的片段:

@Override
public void onStart()
{
  super.onStart();

  // safety check
  if (getDialog() == null)
    return;

  int dialogWidth = ... // specify a value here
  int dialogHeight = ... // specify a value here

  getDialog().getWindow().setLayout(dialogWidth, dialogHeight);

  // ... other stuff you want to do in your onStart() method
}

我使用AlertDialog创建对话框。所以我在OnShowListener中使用了Rodrigo的答案。

dialog.setOnShowListener(new OnShowListener() {

            @Override
            public void onShow(DialogInterface dialogInterface) {
                Display display = getWindowManager().getDefaultDisplay();
                DisplayMetrics outMetrics = new DisplayMetrics ();
                display.getMetrics(outMetrics);
                dialog.getWindow().setLayout((int)(312 * outMetrics.density), (int)(436 * outMetrics.density));
            }

        });

我最终覆盖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);
}

要获得一个几乎覆盖整个屏幕的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);
}

在我的情况下,这是由align_parentBottom="true"给RelativeLayout内的视图引起的。移除所有alignParentBottom的,并将所有布局改为垂直线性布局,问题消失了。


控制你的DialogFragment的宽度和高度的一种方法是确保它的对话框尊重你的视图的宽度和高度,如果它们的值是WRAP_CONTENT。

使用ThemeOverlay.AppCompat.Dialog

实现这一点的一个简单方法是使用Android支持库中包含的themeoverlay . appcompatc . dialog样式。

使用Dialog的DialogFragment:

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View view = inflater.inflate(R.layout.dialog_view, null);

    Dialog dialog = new Dialog(getContext(), R.style.ThemeOverlay_AppCompat_Dialog);
    dialog.setContentView(view);
    return dialog;
}

AlertDialog(警告:minHeight="48dp"):

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View view = inflater.inflate(R.layout.dialog_view, null);

    AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.ThemeOverlay_AppCompat_Dialog);
    builder.setView(view);
    return builder.create();
}

你也可以在创建对话框时将themeoverlay . appcompat_dialog设置为默认主题,将其添加到应用程序的xml主题中。 请注意,许多对话框确实需要默认的最小宽度才能看起来更好。

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- For Android Dialog. -->
    <item name="android:dialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>

    <!-- For Android AlertDialog. -->
    <item name="android:alertDialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>

    <!-- For AppCompat AlertDialog. -->
    <item name="alertDialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>

    <!-- Other attributes. -->
</style>

使用Dialog的DialogFragment,使用android:dialogTheme:

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View view = inflater.inflate(R.layout.dialog_view, null);

    Dialog dialog = new Dialog(getContext());
    dialog.setContentView(view);
    return dialog;
}

AlertDialog的对话片段,使用android:alertDialogTheme或alertDialogTheme(警告:minHeight="48dp"):

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View view = inflater.inflate(R.layout.dialog_view, null);

    AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
    builder.setView(view);
    return builder.create();
}

奖金

在旧的Android api上,对话框似乎有一些宽度问题,因为它们的标题(即使你没有设置一个)。 如果你不想使用themeoverlay . appcompata .Dialog样式,并且你的对话框不需要标题(或者有自定义标题),你可能想要禁用它:

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View view = inflater.inflate(R.layout.dialog_view, null);

    Dialog dialog = new Dialog(getContext());
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(view);
    return dialog;
}

过时的答案,在大多数情况下都行不通

我试图让对话框尊重我的布局的宽度和高度,而不是通过编程指定固定的大小。

我认为android:windowMinWidthMinor和android:windowMinWidthMajor导致了这个问题。即使它们没有包含在我的活动或对话的主题中,它们仍然以某种方式应用到活动主题中。

我想到了三个可能的解决方案。

解决方案1:创建一个自定义对话主题,并在DialogFragment中创建对话时使用它。

<style name="Theme.Material.Light.Dialog.NoMinWidth" parent="android:Theme.Material.Light.Dialog">
    <item name="android:windowMinWidthMinor">0dip</item>
    <item name="android:windowMinWidthMajor">0dip</item>
</style>
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return new Dialog(getActivity(), R.style.Theme_Material_Light_Dialog_NoMinWidth);
}

解决方案2:创建一个用于ContextThemeWrapper的自定义主题,该主题将作为对话框的上下文。如果你不想创建一个自定义对话框主题(例如,当你想使用android:dialogTheme指定的主题时),使用这个。

<style name="Theme.Window.NoMinWidth" parent="">
    <item name="android:windowMinWidthMinor">0dip</item>
    <item name="android:windowMinWidthMajor">0dip</item>
</style>
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return new Dialog(new ContextThemeWrapper(getActivity(), R.style.Theme_Window_NoMinWidth), getTheme());
}

解决方案3(与AlertDialog):强制android:windowMinWidthMinor和android:windowMinWidthMajor到ContextThemeWrapper创建的AlertDialog$Builder。

<style name="Theme.Window.NoMinWidth" parent="">
    <item name="android:windowMinWidthMinor">0dip</item>
    <item name="android:windowMinWidthMajor">0dip</item>
</style>
@Override
public final Dialog onCreateDialog(Bundle savedInstanceState) {
    View view = new View(); // Inflate your view here.
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setView(view);
    // Make sure the dialog width works as WRAP_CONTENT.
    builder.getContext().getTheme().applyStyle(R.style.Theme_Window_NoMinWidth, true);
    return builder.create();
}

下面是在xml中设置DialogFragment宽度/高度的方法。只需要用一个透明背景的框架布局(任何布局都可以)来包装你的viewherarchy。

透明背景似乎是一个特殊的标志,因为当你这样做时,它会自动将framayout的子元素居中。您仍然会在您的片段后面看到全屏变暗,这表明您的片段是活动元素。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/transparent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="@color/background_material_light">

      .....

当我需要使对话片段更宽一点时,我设置minWidth:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minWidth="320dp"
    ... />

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>

最外层布局中的维度在对话框中不起作用。您可以添加一个布局,其中设置的尺寸低于最外层。

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

<LinearLayout
    android:layout_width="xxdp"
    android:layout_height="xxdp"
    android:orientation="vertical">

</LinearLayout>


你可以用百分比表示宽度。

<style name="Theme.Holo.Dialog.MinWidth">
<item name="android:windowMinWidthMajor">70%</item>

在这个例子中,我使用了Holo Theme。


更新2021

对于Kotlin用户,我设计了几个简单的扩展方法,可以将DialogFragment的宽度设置为屏幕宽度的百分比,或者接近全屏:

/**
 * Call this method (in onActivityCreated or later) to set 
 * the width of the dialog to a percentage of the current 
 * screen width.
 */
fun DialogFragment.setWidthPercent(percentage: Int) {
    val percent = percentage.toFloat() / 100
    val dm = Resources.getSystem().displayMetrics
    val rect = dm.run { Rect(0, 0, widthPixels, heightPixels) }
    val percentWidth = rect.width() * percent
    dialog?.window?.setLayout(percentWidth.toInt(), ViewGroup.LayoutParams.WRAP_CONTENT)
}

/**
 * Call this method (in onActivityCreated or later) 
 * to make the dialog near-full screen.
 */
fun DialogFragment.setFullScreen() {
    dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}

然后在你的DialogFragment中或onActivityCreated之后:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    setWidthPercent(85)
}

为子孙后代考虑一下这个答案的其余部分。

问题13:对话片段布局

这真的有点让人麻木。

当创建一个DialogFragment时,你可以选择覆盖onCreateView(它传递一个ViewGroup来附加你的.xml布局)或onCreateDialog,后者没有。

但是你不能同时覆盖这两个方法,因为你很可能会让Android搞不清楚你的对话框布局是否被夸大了!WTF ?

是否覆盖OnCreateView或OnCreateDialog的选择取决于你打算如何使用对话框。

如果你打算允许DialogFragment来控制它自己内部对话框的呈现,那么你需要重写OnCreateView。 如果你打算手动控制DialogFragment的对话框将如何呈现,你需要重写OnCreateDialog。

这可能是世界上最糟糕的事情了。

onCreateDialog疯狂

因此,您正在重写DialogFragment中的onCreateDialog以创建一个自定义的AlertDialog实例以显示在窗口中。酷。但是请记住,onCreateDialog没有接收ViewGroup来附加您的自定义.xml布局。没问题,您只需将null传递给充气方法。

让疯狂开始吧。

当你重写onCreateDialog时,Android完全忽略了你膨胀的.xml布局的根节点的几个属性。这包括但不限于:

background_color layout_gravity layout_width layout_height

这几乎是滑稽的,因为你被要求设置每一个.xml布局的layout_width和layout_height或Android Studio将扇你一个漂亮的小红色耻辱徽章。

光是DialogFragment这个词就让我想吐。我可以写一本充满Android陷阱和混乱的小说,但这是最阴险的一个。

为了回归理智,首先,我们声明一个样式来恢复我们期望的background_color和layout_gravity:

<style name="MyAlertDialog" parent="Theme.AppCompat.Dialog">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:layout_gravity">center</item>
</style>

上面的样式继承自对话框的基本主题(在本例中的AppCompat主题中)。

接下来,我们通过编程的方式应用样式来放回Android刚刚丢弃的值,并恢复标准的AlertDialog外观:

public class MyDialog extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        View layout = getActivity().getLayoutInflater().inflate(R.layout.my_dialog_layout, null, false);
        assert layout != null;
        //build the alert dialog child of this fragment
        AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
        //restore the background_color and layout_gravity that Android strips
        b.getContext().getTheme().applyStyle(R.style.MyAlertDialog, true);
        b.setView(layout);
        return b.create();
    }
}

上面的代码将使您的AlertDialog看起来像一个AlertDialog。也许这就足够了。

但是等等,还有更多!

如果你正在为你的AlertDialog设置一个特定的layout_width或layout_height,当它显示(很可能),然后你猜什么,你还没有完成!

有趣的是,当你意识到如果你试图在你的花哨的新样式中设置一个特定的layout_width或layout_height时,Android也会完全忽略它!:

<style name="MyAlertDialog" parent="Theme.AppCompat.Dialog">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:layout_gravity">center</item>
    <!-- NOPE!!!!! --->
    <item name="android:layout_width">200dp</item>
    <!-- NOPE!!!!! --->
    <item name="android:layout_height">200dp</item>
</style>

要设置一个特定的窗口宽度或高度,你需要使用一个完整的方法来处理LayoutParams:

@Override
public void onResume() {
    super.onResume();
    Window window = getDialog().getWindow();
    if(window == null) return;
    WindowManager.LayoutParams params = window.getAttributes();
    params.width = 400;
    params.height = 400;
    window.setAttributes(params);
}

许多人效仿Android的坏例子,使用WindowManager。LayoutParams到更通用的ViewGroup。LayoutParams,只是为了右转并施放ViewGroup。LayoutParams返回到WindowManager。几行之后的LayoutParams。有效的Java见鬼去吧,这种不必要的强制转换除了使代码更难破译之外,什么也没有提供。

旁注:在Android SDK中有大约20个重复的LayoutParams——这是一个非常糟糕的设计的完美例子。

总之

对于覆盖onCreateDialog的DialogFragments:

要恢复标准AlertDialog的外观和感觉,创建一个设置background_color = transparent和layout_gravity = center的样式,并在onCreateDialog中应用该样式。 要设置特定的layout_width和/或layout_height,可以在onResume中通过LayoutParams编程来实现 为了保持理智,尽量不要去想Android SDK。


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

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

早期的一个解决方案几乎起作用了。我尝试了一些稍微不同的方法,结果对我有用。

(一定要看他的解决方案) 这就是他的解决办法。点击这里 除了builder.getContext(). gettheme (). applystyle (R.style。Theme_Window_NoMinWidth,真正的);

我把它改成

 @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {


        // Use the Builder class for convenient dialog construction
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        // Get layout inflater
        LayoutInflater layoutInflater = getActivity().getLayoutInflater();

        // Set layout by setting view that is returned from inflating the XML layout
        builder.setView(layoutInflater.inflate(R.layout.dialog_window_layout, null));


        AlertDialog dialog = builder.create();

        dialog.getContext().setTheme(R.style.Theme_Window_NoMinWidth);

最后一行是真正的不同之处。


@Override
public void onStart() {
    super.onStart();
    Dialog dialog = getDialog();
    if (dialog != null)
    {
        dialog.getWindow().setLayout(-1, -2);
        dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
        Window window = getDialog().getWindow();
        WindowManager.LayoutParams params = window.getAttributes();
        params.dimAmount = 1.0f;
        window.setAttributes(params);
        window.setBackgroundDrawableResource(android.R.color.transparent);
    }
}

这是最简单的解决方案

我发现的最好的解决方案是重写onCreateDialog()而不是onCreateView()。setContentView()将在膨胀之前设置正确的窗口尺寸。它不需要在资源文件中存储/设置维度、背景颜色、样式等,也不需要手动设置。

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = new Dialog(getActivity());
    dialog.setContentView(R.layout.fragment_dialog);

    Button button = (Button) dialog.findViewById(R.id.dialog_button);
    // ...
    return dialog;
}

简单而扎实:

@Override
    public void onResume() {
        // Sets the height and the width of the DialogFragment
        int width = ConstraintLayout.LayoutParams.MATCH_PARENT;
        int height = ConstraintLayout.LayoutParams.MATCH_PARENT;
        getDialog().getWindow().setLayout(width, height);

        super.onResume();
    }

我没有看到一个令人信服的理由重写onResume或onStart来设置DialogFragment的Dialog中的窗口宽度和高度——这些特定的生命周期方法可以被反复调用,不必要地执行调整代码多次,由于多窗口切换,后台然后前景应用等事情。这种重复的后果是相当微不足道的,但为什么要满足于此呢?

在重写的onActivityCreated()方法中设置宽度/高度将是一个改进,因为这个方法实际上只会在每个DialogFragment实例中调用一次。例如:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    Window window = getDialog().getWindow();
    assert window != null;

    WindowManager.LayoutParams layoutParams = window.getAttributes();
    layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
    window.setAttributes(layoutParams);
}

上面我只是将宽度设置为match_parent,而不考虑设备方向。如果你想要你的横向对话框不那么宽,你可以检查getResources(). getconfiguration()。orientation == Configuration。事先ORIENTATION_PORTRAIT。


添加到FragmentDialog:

public void onResume() {
    Window window = getDialog().getWindow();
    Point size = new Point();
    Display display = window.getWindowManager().getDefaultDisplay();
    display.getSize(size);
    window.setLayout( (int)(size.x * 0.9), WindowManager.LayoutParams.WRAP_CONTENT );
    window.setGravity( Gravity.CENTER );
    super.onResume();
}

这里是kotlin版本

    override fun onResume() {
        super.onResume()

        val params:ViewGroup.LayoutParams = dialog.window.attributes
        params.width = LinearLayout.LayoutParams.MATCH_PARENT
        params.height = LinearLayout.LayoutParams.MATCH_PARENT
        dialog.window.attributes = params as android.view.WindowManager.LayoutParams
    }

这将会非常有效。

@Override
public void onResume() {
    super.onResume();
    Window window = getDialog().getWindow();
    if(window == null) return;
    WindowManager.LayoutParams params = window.getAttributes();
    params.width = 400;
    params.height = 400;
    window.setAttributes(params);
}

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


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

<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)
}

使用RelativeLayout作为DialogFragment的父元素


public void onResume() {

    Window window = Objects.requireNonNull(getDialog()).getWindow();
    Point size = new Point();
    assert window != null;
    Display display = window.getWindowManager().getDefaultDisplay();
    display.getSize(size);
    window.setLayout( (int)(size.x * 0.9), (int) (size.y * 0.75));
    window.setGravity( Gravity.CENTER );
    super.onResume();
    

}

我把@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
    )
}