13

Im trying to display an DialogFragment with match_parent both for height and width but it happens that on top the DialogFragment is being displayed below StatusBar.

The DialogFragment is applying some default value for padding on bottom, right, left, and top. But the top padding should start counting from statusBar and not from the total screen size.

How can I set DialogFragment to be match_parent, but have the normal/default padding on top,bottom,right,left?

azizbekian
  • 60,783
  • 13
  • 169
  • 249
Bugdr0id
  • 2,962
  • 6
  • 35
  • 59

2 Answers2

26

By default Dialog would be applied FLAG_LAYOUT_IN_SCREEN and FLAG_LAYOUT_INSET_DECOR flags. An excerpt from 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 is the flag, that you do not want to be applied. From docs:

Window flag: a special option only for use in combination with FLAG_LAYOUT_IN_SCREEN. When requesting layout in the screen your window may appear on top of or behind screen decorations such as the status bar. By also including this flag, the window manager will report the inset rectangle needed to ensure your content is not covered by screen decorations. This flag is normally set for you by Window as described in setFlags(int, int).

By default, windowIsFloating is enabled. So, if you declare your custom theme:

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

Then in your DialogFragment:


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

Where the layout content is following:

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

Then you'll get this output:


If you want the pink layout to be laid out below status bar and above navigation bar, then just apply android:fitsSystemWindows="true" to your root ViewGroup:

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

    <View .../>

</FrameLayout>

This will be the output:

You can see the meaning of that flag in my this answer.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
  • Adding it to onResume(), does not solve the problem. Right now i have the view wrapping height and width. – Bugdr0id Sep 28 '17 at 13:13
  • Are you performing `getDialog().getWindow().setFlags(...)`? – azizbekian Sep 28 '17 at 13:14
  • 1
    Yes, im setting: getDialog().getWindow().setFlags(FLAG_LAYOUT_IN_SCREEN, FLAG_LAYOUT_IN_SCREEN); – Bugdr0id Sep 28 '17 at 13:22
  • I think I've misunderstood your question. `How can I set DialogFragment to be match_parent, but have the normal/default padding on top,bottom,right,left?` what paddings do you want to have? – azizbekian Sep 29 '17 at 09:09
  • the image you have posted shows my problem :D i want to avoid my dialog to be below status bar. – Bugdr0id Sep 29 '17 at 09:17
  • 1
    I fail to have the dialogfragment coverd by a transparent or translucent statusbar... – YuTang Nov 10 '19 at 08:38
-1

The accepted answer (@azizbekian) wasn't enough for me, I also needed to apply this to the dialog (onCreateDialog):

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

or this if you want under status bar but above nav bar:

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
hmac
  • 267
  • 3
  • 9