12

我试图在高度和宽度上显示一个带有 match_parent 的 DialogFragment,但碰巧在顶部的 DialogFragment 显示在 StatusBar 下方。

DialogFragment 正在为底部、右侧、左侧和顶部的填充应用一些默认值。但顶部填充应从 statusBar 开始计数,而不是从总屏幕尺寸开始计数。

如何将 DialogFragment 设置为 match_parent,但在顶部、底部、右侧、左侧有正常/默认填充?

4

2 回答 2

24

默认情况下Dialog将应用FLAG_LAYOUT_IN_SCREENFLAG_LAYOUT_INSET_DECOR标志。摘自PhoneWindow


        mIsFloating = a.getBoolean(R.styleable.Window_windowIsFloating, false);
        int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR)
                & (~getForcedWindowFlags());
        if (mIsFloating) {
            setLayout(WRAP_CONTENT, WRAP_CONTENT);
            setFlags(0, flagsToUpdate);
        } else {
            setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);
        }

FLAG_LAYOUT_INSET_DECOR是标志,您不想被应用。来自文档

窗口标志:仅与FLAG_LAYOUT_IN_SCREEN结合使用的特殊选项。在屏幕中请求布局时,您的窗口可能会出现在屏幕装饰(例如状态栏)的顶部或后面。通过还包括此标志,窗口管理器将报告确保您的内容不被屏幕装饰覆盖所需的插入矩形。此标志通常由Window为您设置,如setFlags(int, int)中所述。

默认情况下,windowIsFloating已启用。因此,如果您声明自定义主题:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>

</style>

<style name="MyTheme" parent="@style/ThemeOverlay.AppCompat.Dialog.Alert">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
    <item name="android:windowFrame">@null</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@null</item>
    <item name="android:windowIsFloating">false</item>
    <item name="android:backgroundDimEnabled">false</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowNoTitle">true</item>
</style>

然后在你的DialogFragment


    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = new Dialog(getActivity(), R.style.MyTheme);
        dialog.setContentView(R.layout.your_layout);
        return dialog;
    }

布局内容如下:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <View
        android:layout_gravity="center_horizontal"
        android:background="@color/colorAccent"
        android:layout_width="250dp"
        android:layout_height="700dp"/>

</FrameLayout>

然后你会得到这个输出:


如果您希望将粉红色布局布置在状态栏下方和导航栏上方,则只需应用于android:fitsSystemWindows="true"您的 root ViewGroup

<FrameLayout
    ...
    android:fitsSystemWindows="true">

    <View .../>

</FrameLayout>

这将是输出:

您可以在我的这个答案中看到该标志的含义。

于 2017-09-28T12:59:50.970 回答
-1

接受的答案(@azizbekian)对我来说还不够,我还需要将其应用于对话框(onCreateDialog):

window?.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)

或者如果你想在状态栏下方但在导航栏上方:

window.decorView.systemUiVisibility =
window.decorView.systemUiVisibility or
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
 
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.statusBarColor = Color.TRANSPARENT
于 2021-09-29T16:30:32.343 回答