Ответ 1
Увидел ту же проблему. Выбрал его в моем приложении, удалив fitSystemWindows из объявления активности и добавив paddingTop к фрагменту. Очевидно, это не идеальное решение, но, похоже, работает.
В моем приложении есть одно действие, в котором размещаются разные фрагменты для каждого раздела. Недавно я сделал индикатор состояния полупрозрачным, установив fitSystemWindows
в true
, который установил его на цвет фона приложения. Это прекрасно для фрагментов, у которых есть панель инструментов, где цвета совпадают, например:
Однако у одного из моих фрагментов есть фотография и полупрозрачная панель инструментов, поэтому я хотел бы, чтобы фотография занимала пространство строки состояния, а не цвет фона.
Я считаю, что решение состоит в том, чтобы установить fitSystemWindows
в false
только для этого фрагмента и вручную добавить отступ к полупрозрачной панели инструментов. Выполнение этого программно, похоже, не имеет никакого эффекта, что я могу делать неправильно?
Вот мой основной вид деятельности:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_parent_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
<!-- Container for various fragment layouts, including nav drawer and tool bar -->
</RelativeLayout>
И изнутри моего фрагмента onCreateView():
RelativeLayout daddyLayout = (RelativeLayout)getActivity().findViewById(R.id.main_parent_view);
daddyLayout.setFitsSystemWindows(false);
daddyLayout.invalidate();
Кажется, это не имеет никакого эффекта:
Если я установил fitSystemWindows
в false в main_parent_view
, заполнение строки состояния исчезнет, и оно работает, но, очевидно, влияет на каждый фрагмент.
Увидел ту же проблему. Выбрал его в моем приложении, удалив fitSystemWindows из объявления активности и добавив paddingTop к фрагменту. Очевидно, это не идеальное решение, но, похоже, работает.
Вы можете использовать CoordinatorLayout
в качестве корневого представления активности, а затем setFitsSystemWindows(boolean)
будет работать.
Это связано с тем, что, как объясняется в этом сообщении в блоге, DrawerLayout
и CoordinatorLayout
имеют разные правила использования fitsSystemWindows
для них - они оба используют его для вставки их дочерних представлений, но также вызывают dispatchApplyWindowInsets()
для каждого дочернего элемента, позволяя им получить доступ к свойству fitsSystemWindows="true"
.
Это отличие от поведения по умолчанию с макетами, такими как FrameLayout
, где при использовании fitsSystemWindows="true"
используется все вставки, слепое применение отступов, не сообщая ни одного дочернего вида (что часть "глубина первой" в блоге).
Я разрешаю этот вопрос в 4.4
if(test){
Log.d(TAG, "fit true ");
relativeLayout.setFitsSystemWindows(true);
relativeLayout.requestFitSystemWindows();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}else {
Log.d(TAG, "fit false");
relativeLayout.setFitsSystemWindows(false);
relativeLayout.requestFitSystemWindows();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
Ну, вы находитесь в ситуации дилеммы, потому что с одной стороны вам нужно применять вставки (потому что Toolbar
должен быть правильно дополнен), а с другой стороны вы должны не применять вставки ( потому что вы хотите, чтобы ImageView
отображался в строке состояния).
Оказывается там хороший API, предоставляемый каркасом для этого случая:
ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> {
((ViewGroup.MarginLayoutParams) v.getLayoutParams()).topMargin =
insets.getSystemWindowInsetTop();
return insets.consumeSystemWindowInsets();
});
Предполагая, что ваш корневой макет имеет android:fitsSystemWindows="true"
, теперь соответствующие вставки будут применены к вашему Toolbar
только, а не к ImageView
.
Но, есть проблема.
Проблема заключается в том, что ваш корневой макет RelativeLayout
, который не передает своим детям информацию о вставках. Также не отображаются его раскладки (LinearLayout
, FrameLayout
).
Если у вас в качестве корневого макета один из "материальных" макетов (CoordinatorLayout
, DrawerLayout
), тогда детям будут отправляться эти вставки окна.
Другой вариант заключается в подклассе RelativeLayout
и отправке WindowInsets
в
детей вручную.
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; index++)
getChildAt(index).dispatchApplyWindowInsets(insets); // let children know about WindowInsets
return insets;
}
Вы можете увидеть этот ответ для подробного объяснения с тем же самым требованием, которое у вас есть.