如何设置DialogFragment的宽度和高度?


173

我在一个xml布局文件中指定DialogFragment的布局(我们称它为layout_mydialogfragment.xml),尤其是它的layout_widthlayout_height属性(可以100dp这么说)。然后,我在DialogFragment的onCreateView(...)方法中将此布局充气,如下所示:

View view = inflater.inflate(R.layout.layout_mydialogfragment, container, false);

不幸的是,我发现对话框(DialogFragment)出现时,它不遵守XML布局文件中指定的layout_widthlayout_height(并且对话框根据内容的不同而收缩或扩展)。任何人都知道是否或者如何让我的对话框尊重其layout_widthlayout_height在其xml布局文件中指定?目前,我必须在DialogFragment的onResume()方法中再次指定对话框的宽度和高度,如下所示...

getDialog().getWindow().setLayout(width, height);

...因此,不合需要的是,必须记住在以后两个地方对对话框的宽度和高度进行任何更改。


2
考虑接受jpmcosta的答案。这不是黑客,它实际上可以解决此问题。
Bogdan Zurac

Answers:


168

如果直接从资源值转换:

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


3
在我的情况下,此答案不起作用(对于DialogFragment)。我不得不使用FragmentLayout参数来更改显示窗口的大小。
Rusfearuth 2012年

3
我不得不将布局包装进去RelativeLayout,这对我有所帮助。非常感谢您的解决方案-它节省了我很多时间。
约翰尼·多伊

62
一旦我意识到必须在onResume()而不是中,这对我来说非常有用(Android 4.0+)onCreateView()。(我的根目录布局是包装在ScrollView中的RelativeLayout。)
Jonik

14
在某些情况下有用:使用整个屏幕宽度:int width = getResources().getDisplayMetrics().widthPixels
Jonik

6
为Jonik +1。理查德为-1。我一直使用支持片段,却从未能够使用它onCreateDialog()。需要进来onResume()
MinceMan 2014年

146

我最终Fragment.onResume()从基础对话框覆盖并获取了属性,然后在那里设置了width / height参数。我将最外面的布局高度/宽度设置为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);
}

2
谢谢 !这个对我有用 !而且,这是一种优雅的方式。
AntoineP 2014年

1
@jmaculate-快速问题:当您投射到时(android.view.WindowManager.LayoutParams),您从哪里投射它?选择正确的导入以LayoutParams显示在函数的前三行时,我感到困惑。最终选择了(android.view.WindowManager.LayoutParams)。这应该是正确的吗?
Dev-iL 2014年

@ Dev-iL getAttributes()返回WindowManger.LayoutParams,但是在我的情况下,我将其隐式转换为ViewGroup.LayoutParams,因为这就是我所需要的(有效Java,第52项)-我将编辑问题以反映这一点
jmaculate

1
如果您需要再次将其转换为android.view.WindowManager.LayoutParams,则在ViewGroup.LayoutParams上面使用三行代码是没有用的...您在这里没有任何灵活性。无论如何,谢谢您的好回答!
凯文·罗巴特尔

2
这是最好的解决方案。您甚至可以将特定的像素值与MATCH_PARENT或WRAP_CONTENT一起使用。
Koesh

98

我得到了固定大小的DialogFragment,它在XML主布局中定义了以下内容(在我的情况下为LinearLayout):

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

4
我发现我需要在Honeycomb中使用midWidth和minHeight-但在ICS中不需要。
daveywc

1
乍一看似乎可行,但应该避免。根据设备的宽度,视图将在屏幕外继续显示,因此如果您在右下角有按钮,它们将不会出现。
CodyEngel '18

视图不在屏幕上继续。即使这些边界小于指定的minWidth和minHeight,Android系统似乎也可以确保DialogFragment保持在视图边界之内(以很小的边距)。
Lensflare '18年

51

在我看来,唯一有效的方法是此处指出的解决方案: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
}

完美的解决方案,并且在博客中有很好的解释。
varun bhardwaj '16

+1 getDialog().getWindow().setLayout(dialogWidth, dialogHeight); 非常适合DialogFragment。但是我不了解安全检查。为什么我们要检查null
tpk

3
@ 2943-仅仅因为不能保证Dialog(的孩子DialogFragment)在请求时将可用。当我们呼叫时,Android可能会传回null getDialog()
rmir​​abelle

@mirabelle如果使用对话框的onStart回调,对话框如何为null?
rommex

49

控制您DialogFragment的宽度和高度的一种方法是确保其对话框尊重您视图的宽度和高度(如果其值为)WRAP_CONTENT

使用 ThemeOverlay.AppCompat.Dialog

一种简单的实现方法是利用ThemeOverlay.AppCompat.DialogAndroid支持库中包含的样式。

DialogFragmentDialog

@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;
}

DialogFragmentAlertDialog(caveat:)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>

DialogFragment与一起Dialog使用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;
}

DialogFragment与一起AlertDialog使用,android:alertDialogTheme或使用或alertDialogTheme(caveat:)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上,Dialogs似乎有一些宽度问题,因为它们的标题(即使您未设置)。
如果您不想使用ThemeOverlay.AppCompat.Dialog样式并且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:windowMinWidthMinorandroid:windowMinWidthMajor导致了问题。即使它们未包含在my Activity或主题中Dialog,它们仍以Activity某种方式被应用于主题。

我提出了三种可能的解决方案。

解决方案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,将作为Context该对话框。如果您不想创建自定义对话框主题(例如,当您要使用所指定的主题时),请使用此选项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:windowMinWidthMinorandroid:windowMinWidthMajorContextThemeWrapper由创建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();
}

4
我真的不知道为什么这不是公认的答案。从字面上看,这是唯一可行的答案,而不是hack(我主要是在为您的第一个解决方案辩护)。
Bogdan Zurac

1
不幸的是,花了一个小时弄清楚如何解决后才发现了这一点!
brainvision '16

解决方案3挽救了我的生命。非常感谢
Simon,

我能够在较旧的Android API上重现您的问题。添加了一些可能对您有帮助的替代方法。
jpmcosta

解决方案1对我有用。我只是用作Theme.MaterialComponents.Light.Dialog父项,并在的构造函数中使用了此样式MaterialAlertDialogBuilder。经过1个小时的研究,偶然发现了您的答案。谢谢和竖起大拇指。
Shahood ul Hassan

39

难题#13:DialogFragment布局

确实有点麻木。

创建时DialogFragment,您可以选择覆盖onCreateView(传递一个,ViewGroup以将.xml布局附加到)或onCreateDialog,而不覆盖。

您绝对不能重写这两种方法,因为您很可能将Android的对话框布局何时或是否变得膨胀感到困惑!WTF?

选择是覆盖OnCreateDialog还是OnCreateView取决于您打算如何使用对话框。

  • 如果要在窗口中启动对话框(正常行为),则应覆盖OnCreateDialog
  • 如果您打算将对话框片段嵌入现有的UI布局中(较不常见的FAR),则应该重写OnCreateView

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

onCreateDialog 疯狂

所以,你覆盖onCreateDialog在你DialogFragment创建一个定制的实例AlertDialog在窗口中显示。凉。但是请记住,onCreateDialog没有ViewGroup将您的自定义.xml布局附加到的信息。没问题,您只需传递null给该inflate方法即可。

让疯狂开始吧。

当您覆盖时onCreateDialog,Android 完全忽略要膨胀的.xml布局根节点的几个属性。这包括但可能不限于:

  • background_color
  • layout_gravity
  • layout_width
  • layout_height

这几乎很可笑,因为您需要设置layout_widthlayout_height,每一个.xml Layout或Android Studio都会给您打上漂亮的红色耻辱徽章。

只是这个 DialogFragment使我想吐。我可以写一本充满Android陷阱和陷阱的小说,但这是最有深度的小说之一。

为了恢复理智,首先,我们声明一种样式来恢复JUST background_colorlayout_gravity我们期望:

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

上面的样式继承自Dialogs的基本主题(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一遍。也许这已经足够了。

但是,等等,还有更多!

如果您希望设置一个“ 特定规格” layout_widthlayout_heightAlertDialog它设置显示时间(很有可能),那么请猜测一下,您还没有完成!

当您意识到如果尝试设置特定的样式layout_widthlayout_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>

要设置特定的窗口宽度或高度,请直接使用整个“ nuther”方法并进行以下处理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是该死的,不必要的强制转换除了使代码更难以解密之外,还提供了其他功能。

旁注:LayoutParams整个Android SDK 都有TWENTY重复,这是彻底糟糕的设计的完美示例。

综上所述

对于DialogFragment覆盖的onCreateDialog

  • 要恢复标准的AlertDialog外观,请创建设置background_color= transparentlayout_gravity= 的样式,center然后在中应用该样式onCreateDialog
  • 要设置一个特定的layout_width和/或layout_height,以编程方式onResumeLayoutParams
  • 为了保持理智,请尽量不要考虑使用Android SDK。

13
阅读此答案使我想哭。
Bassinator

3
杜德(Dude),您恰好描述了我现在正在经历的事情。
MertGülsoy17年

2
Android很烂。我感觉你兄弟 需要所有内容的上下文,应用程序进程被杀死,缺少某些东西的支持库,列表还在继续
DennisVA'Aug

1
@rmirabelle-这个答案实际上有帮助,您实际上可以编写一个中等博客,并且可能对很多人有帮助。就我而言,我使用的是约束布局和DialogFragment,因此在Android 9中被忽略时,在Android 9以下它可以正常工作。我添加了样式-“ android:windowMinWidthMajor”,“ android:windowMinWidthMinor”,它开始正常工作。–
Rahul


14

当我需要使DialogFragment宽一点时,我要设置minWidth:

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

1
我认为最好的解决方案!
Fabian Knapp

如果您想缩小范围怎么办?
丹尼尔(Daniel)

8

我看不出一个令人信服的理由来覆盖onResumeonStart设置的宽度和高度Window范围内DialogFragmentDialog-这些特定的生命周期方法可以得到反复和不必要的称为执行该调整的代码不止一次因之类的多窗口切换,backgrounding然后将应用程序前台化,依此类推。重复的结果相当琐碎,但是为什么要解决呢?

onActivityCreated()实际上,在覆盖的方法中设置width / height 会有所改善,因为该方法实际上每个实例仅被调用一次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事先检查是否。


6

最外层布局中的尺寸在对话框中不起作用。您可以在最外层下方设置尺寸的位置添加布局。

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


5

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

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

5

这是在xml中设置DialogFragment宽度/高度的方法。只需将viewHierarchy包装在具有透明背景的Framelayout中(任何布局都可以使用)。

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

<?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">

      .....

我将尝试一下,因为如果它能始终如一地工作,那么这将是一种非常出色的方法,可以用XML编码部分布局,并用代码进行编码。谢谢
rmir​​abelle

我喜欢这种方法的想法,但是经过测试,它产生的布局不同于简单地以编程方式更改高度和宽度的布局。例如,总宽度被强制减小为AlertDialog提供的最大宽度(可能是由于Android样式)。当我仅通过代码设置w和h时,AlertDialog样式被否决。但是,这可能适合许多需求,并且是个好主意。历史上最糟糕的SDK万岁。
rmir​​abelle

对于onCreateView来说效果很好,直到我想将内部宽度更改为match_parent ...
tudor

5

这是科特林版

    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
    }

4

您可以使用百分比表示宽度。

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

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


3

您可以在下面的代码中从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();

2

我使用AlertDialog.Builder创建对话框,因此在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));
            }

        });

(主要供将来的读者使用:)请参阅stackoverflow.com/a/7979823/3372061Snicolas中“ DialogFragmentvs AlertDialog” 的讨论中的评论。
Dev-iL 2014年

2

在Android 6.0上运行时,遇到了同样的问题。不管自定义视图root 中的实际设置如何,AlertDialog都会默认width使用主题中的预定义设置。我能够将其设置为正确调整的。无需进一步调查,似乎可以确定实际元素并确定其根源。widthLayoutwidthloading_message TextViewLayout周围,从而可以按预期工作。以下是加载对话框的XML布局,可以width正确设置对话框。使用此库进行动画处理。

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

2

简单而坚实:

@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();
    }

2

在我的情况下DialogFragment占据全尺寸的活动像Fragment。的DialogFragment基于XML布局,而不是AlertDialog。我的错误是将对话框片段添加到FragmentManager通常的片段中:

fragmentManager?.beginTransaction()?.run {
    replace(R.id.container, MyDialogFragment.newInstance(), MyDialogFragment.TAG)
    addToBackStack(MyDialogFragment.TAG)
}?.commitAllowingStateLoss()

相反,我需要show对话框片段:

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
}

现在,它已定义宽度和高度,而不是完整的活动大小。

我想说一下onCreateViewonCreateDialog。如果您有一个基于布局的对话框片段,则可以使用这两种方法中的任何一种。

1)如果使用onCreateView,则应该使用onActivityCreated设置宽度。

2)如果使用onCreateDialog代替onCreateView,则可以在那里设置参数。onActivityCreated不需要。

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
}

您节省了我的一天,在onActivityCreated中设置宽度对我有用。
夏格·麦迪

@ManishKumarSharma,祝你好运!
CoolMind

1

在我的情况下,这是由于align_parentBottom="true"在内的某个视图引起的RelativeLayout。删除了所有的alignParentBottom并将所有布局更改为垂直LinearLayouts,问题就消失了。


1

将自定义对话框布局的父布局设置为RelativeLayout,自动获得通用的宽度和高度。

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

这对我有用。我想使用ConstraintLayout在对话框中布置控件,因此我将RelativeLayout用于根布局,然后将ConstraintLayout直接放在其中。这给了我一个正常大小的对话框。当我将ConstraintLayout设置为根而不更改任何其他内容时,对话框的宽度会爆裂到不太宽!
leafcutter

1

较早的解决方案之一几乎奏效。我尝试了一些稍有不同的方法,最终为我工作。

(请确保你看看他的解决方案),这是他的解决方案... 点击这里 它的工作除外: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);

最后一行确实有什么不同。


0
@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);
    }
}

0

这是最简单的解决方案

我发现的最佳解决方案是覆盖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;
}

0

添加到您的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();
}

0

这将完美地工作。

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

这几乎是3年前的公认答案。
阿迪尔·侯赛因

-4

要获得一个涵盖几乎所有屏幕的对话框:首先定义一个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()方法之前调用ScreenParamater。

@Override
public void onResume()
{
    super.onResume();
    ScreenParameters s = new ScreenParameters();
    getDialog().getWindow().setLayout(s.Width , s.Height);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.