Display DialogFragment content below status bar

▼魔方 西西 提交于 2019-12-20 14:48:53

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/46467776/display-dialogfragment-content-below-status-bar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!