Отображать содержимое DialogFragment под строкой состояния

Я пытаюсь отобразить DialogFragment с match_parent как по высоте, так и по ширине, но бывает, что сверху DialogFragment отображается под StatusBar.

DialogFragment применяет некоторое значение по умолчанию для заполнения внизу, справа, слева и сверху. Но верхний отступ должен начинать отсчет от строки состояния, а не от общего размера экрана.

Как я могу установить DialogFragment равным match_parent, но иметь нормальное/по умолчанию заполнение сверху, снизу, справа, слева?




Ответы (1)


По умолчанию будет применяться Dialog FLAG_LAYOUT_IN_SCREEN и FLAG_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" к корневому каталогу ViewGroup:

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

    <View .../>

</FrameLayout>

Это будет вывод:

Вы можете увидеть значение этого флага в моем этом ответе.

person azizbekian    schedule 28.09.2017
comment
Добавление его в onResume() не решает проблему. Прямо сейчас у меня есть высота и ширина обертывания представления. - person Bugdr0id; 28.09.2017
comment
Вы исполняете getDialog().getWindow().setFlags(...)? - person azizbekian; 28.09.2017
comment
Да, я устанавливаю: getDialog().getWindow().setFlags(FLAG_LAYOUT_IN_SCREEN, FLAG_LAYOUT_IN_SCREEN); - person Bugdr0id; 28.09.2017
comment
Я думаю, что неправильно понял ваш вопрос. How can I set DialogFragment to be match_parent, but have the normal/default padding on top,bottom,right,left? какие прокладки вы хотите иметь? - person azizbekian; 29.09.2017
comment
изображение, которое вы разместили, показывает мою проблему: D, я хочу, чтобы мой диалог не находился ниже строки состояния. - person Bugdr0id; 29.09.2017
comment
Мне не удается закрыть фрагмент диалога прозрачной или полупрозрачной панелью состояния... - person YuTang; 10.11.2019