Отображать содержимое DialogFragment под строкой состояния
Я пытаюсь отобразить DialogFragment с match_parent как по высоте, так и по ширине, но бывает, что сверху DialogFragment отображается под StatusBar.
DialogFragment применяет некоторое значение по умолчанию для заполнения снизу, справа, слева и сверху. Но верхний отступ должен начинаться с statusBar, а не от общего размера экрана.
Как я могу установить DialogFragment равным match_parent, но иметь нормальный / стандартный отступ сверху, снизу, справа, слева?
2 ответа
По умолчанию 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>
Это будет вывод:
Вы можете увидеть значение этого флага в моем ответе.
Принятого ответа (@azizbekian) мне было недостаточно, мне также нужно было применить его к диалогу (onCreateDialog):
window?.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)