如何让对话框样式的活动窗口充满屏幕?

145

我正在使用一个带有对话框主题的活动,我想让它成为全屏幕。我尝试了各种方法,甚至通过WindowManager手动将窗口扩展到全宽度和全高度,但是都没有效果。

显然,对话框窗口(或具有对话框主题的活动)仅会根据其内容进行扩展,但即使如此也并不总是有效。例如,我显示了一个宽度和高度均设置为FILL_PARENT的进度条圆圈(所在布局容器也是),但仍然,对话框会围绕着小得多的进度条而不是填满整个屏幕。

必须有一种方法可以在对话框窗口内显示小物件,同时使它们扩展到全屏幕大小,而不改变它们的大小吗?


2
有趣的一点: 当将布局容器的宽度和高度设置为实际像素值时,对话框会相应地调整大小。但是当将其设置为FILL_PARENT时,则不会... - mxk
真的吗?该活动实例化的布局,是否具有设置为fill_parent的父Relative或LinearLayout标记的高度和宽度?我已经实现了一些具有对话框主题的活动,并且从未遇到过占用整个屏幕的问题。 - MattC
是的,该活动具有一个LinearLayout,宽度和高度均设置为FILL_PARENT。 - mxk
我使用了一个变通方法来解决问题,但由于这不是一个好的解决方案,我会让这个问题保持开放状态。我的做法是子类化LinearLayout并重写其onMeasure()方法,该方法负责在布局周期中确定视图的大小,并将其修复为屏幕的宽度和高度。然而,这并不正确,因为它没有考虑到菜单栏所占用的空间,所以容器实际上比屏幕上看起来的要高(带有所有奇怪的副作用,如子项消失在屏幕的非可见区域)。 - mxk
我找到了正确的解决方案,请看下面的答案。 - mxk
看一下其他帖子中的这个回答,或许可以有所帮助。https://dev59.com/lW025IYBdhLWcg3wNC92#7655350 - Hugo
10个回答

327

我找到了解决方案:

在你的Activity中,如果已经设置了Theme.Dialog风格,请执行以下操作:

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

    setContentView(R.layout.your_layout);

    getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}

在调用setContentView()之后,重要的是要调用Window.setLayout(),否则它将无法起作用。


5
谢谢,节省了我的时间,我不可能自己搞明白这个问题!但是你知道为什么我们必须在代码中显式地指定,为什么对于主题为对话框的活动,fill_parent不能通过XML工作? - sat
3
我的对话框无法填充整个宽度,无论是通过XML还是通过这种方法。我正在焦虑不安。 - eitama
6
它是:import android.view.ViewGroup.LayoutParams; - user942821
11
FILL_PARENT现在已被弃用,使用MATCH_PARENT代替。 - AlexV
4
它没有填满整个屏幕,就像每边都有一小段留白。 - Machado
显示剩余7条评论

73

您可以将这些值添加到您的样式中:android:windowMinWidthMajor和android:windowMinWidthMinor

<style name="Theme_Dialog" parent="android:Theme.Holo.Dialog">
    ...
    <item name="android:windowMinWidthMajor">97%</item>
    <item name="android:windowMinWidthMinor">97%</item>
</style>

3
最简单的解决方案。它也可以与appcompat支持库一起使用。谢谢。 - Muhammad Saqib
这应该是被接受的答案。这是最合适和干净的方法。考虑使用parent="@style/Theme.AppCompat.Light.Dialog"。 - Kirill Karmazin
这似乎应该可以工作,但对我来说却不行。嗯,我想知道为什么。也许自2014年以来有些事情已经改变了。 - SMBiggs

54

我只想让屏幕填充80%,所以我做了以下操作:

        DisplayMetrics metrics = getResources().getDisplayMetrics();
        int screenWidth = (int) (metrics.widthPixels * 0.80);

        setContentView(R.layout.mylayout);

        getWindow().setLayout(screenWidth, LayoutParams.WRAP_CONTENT); //set below the setContentview

只有当我将getwindow().setLayout...这行代码放在setContentView(..)之后才能正常工作。

感谢@Matthias


13

将您的dialog_custom_layout.xml布局包装到RelativeLayout中,而不是其他任何布局。这对我有用。


1
同样的问题,宽度和高度完全错误,无法找到解决方法。将根布局转换为RelativeLayout也解决了我的问题! - SharpMobileCode

9

对话框 这可能对某些人有帮助。 我想要一个对话框占据整个屏幕宽度。搜寻了很多但都没有找到有用的内容。最终我找到了以下方法:

mDialog.setContentView(R.layout.my_custom_dialog);
mDialog.getWindow().setBackgroundDrawable(null);

在添加了这个代码后,我的对话框会以全屏宽度显示。

7

对于使用"Theme.AppCompat.Dialog"或任何其他"Theme.AppCompat.Dialog"派生主题的人,此答案是一个解决方法,例如"Theme.AppCompat.Light.Dialog"、"Theme.AppCompat.DayNight.Dialog"等。我自己必须使用AppCompat对话框,因为我在所有活动中使用AppCompatActivity作为扩展。如果我们使用接受的答案,会出现让对话框在每个方向上(上、右、下、左)都有填充的问题。

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

    setContentView(R.layout.your_layout);

    getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}

在你的Activity的样式中,添加以下代码:
<style name="DialogActivityTheme" parent="Theme.AppCompat.Dialog">
    <item name="windowNoTitle">true</item>
    <item name="android:windowBackground">@null</item>
</style>

正如您所注意到的,导致对话框产生内边距的问题是“android:windowBackground”,因此我将窗口背景设置为空。


2

在最高层布局中设置最小宽度。

android:minWidth="300dp"

例如:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="300dp">

<!-- Put remaining contents here -->

</LinearLayout>

2

Matthias的回答基本上正确,但仍然无法填满整个屏幕,因为它两侧有一小段填充(由@Holmes指出)。除了他的代码之外,我们可以通过扩展Theme.Dialog样式并添加一些属性来解决这个问题。

<style name="MyDialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
</style>

然后,我们只需声明具有主题设置为MyDialog的Activity:

<activity
    android:name=".FooActivity"
    android:theme="@style/MyDialog" />

2

这对像我这样的人很有帮助。创建自定义对话框样式:

<style name="MyDialog" parent="Theme.AppCompat.Light.Dialog">
    <item name="windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowIsFloating">false</item>
</style>

AndroidManifest.xml文件中为需要的活动设置主题:
<activity
        android:name=".CustomDialog"
        ...
        android:theme="@style/MyDialog"/>

那就这样,不需要编写程序调用方法。

仍然在每个边缘(顶部、右侧、底部和左侧)显示填充,并且如果我们需要显示状态栏,这种解决方案将失败。 - HendraWD
如果您在每个侧面都有填充,请查看 https://dev59.com/53M_5IYBdhLWcg3wfTA0#39590004 - HendraWD

0
在您的清单文件中定义我们的活动。
<activity
        android:name=".YourPopUpActivity"
        android:theme="@android:style/Theme.Holo.Dialog" >
    </activity>

没有操作栏
<activity android:name=".YourPopUpActivity"
            android:theme="@android:style/Theme.Holo.Dialog.NoActionBar"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接