Использование windowTranslucentStatus с CollapsingToolbarLayout
Я пытаюсь получить эффект, подобный тому, что видно в Google Play.
У меня есть схема ниже, чтобы показать прозрачную панель инструментов с изображением позади нее. Когда пользователь прокручивает, на изображении появляется эффект параллакса, когда он прокручивается за пределы экрана. Панель инструментов возвращается, когда пользователь прокручивает вверх, а изображение возвращается только тогда, когда пользователь попадает в область списка.
Это все прекрасно работает.
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/background_material_dark">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:statusBarScrim="#09b"
app:contentScrim="#09f">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/location_banner"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Проблема
Когда я устанавливаю windowTranslucentStatus в true. Содержимое в представлении перемещается вверх, чтобы находиться под строкой состояния, но содержимое CollapsingToolbarLayout перемещается вверх вдвое по высоте строки состояния (CollapsingToolbarLayout сохраняет правильную высоту).
Это означает, что часть верхней части изображения обрезана, и теперь панель действий отображается под строкой состояния, а не под ней. Как побочный эффект этого теперь есть отступ в нижней части CollapsingToolbarLayout той же высоты, что и строка состояния
Вот как это выглядит без windowTranslucentStatus. Все здесь работает отлично
windowTranslucentStatus установлен в true
Пользователь прокручивает список снизу вверх (не сверху)
7 ответов
В библиотеке дизайна появилось обновление. Я предполагаю, что проблема, опубликованная выше, была ошибкой.
При обновлении библиотеки дизайна до последней версии эта проблема больше не возникает.
Теперь я удалил все fitsSystemWindows="true", кроме ImageView (поскольку это должно отображаться в строке состояния).
Я также удалил минус-отступ с панели инструментов.
Это моя тема для 21+
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:textColorPrimary">@android:color/white</item>
</style>
Теперь все работает как положено
Добавьте fitsSystemWindows в макет и установите значение true.
Обновить
Извините за мой неполный ответ. Вы должны добавить fitsSystemWindows="true" в макет XML, как показано ниже.
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/background_material_dark"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:statusBarScrim="#09b"
app:contentScrim="#09f"
android:fitsSystemWindows="true">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/location_banner"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
android:fitsSystemWindows="true"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Как сказал Стимсони, лучший способ достичь этого
Добавьте android:fitsSystemWindows="true" в CoordiatorLayout, AppBarLayout и ImageView.
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="256dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
android:alpha="0.75"
android:src="@drawable/foo"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>...
Как только строка состояния становится прозрачной и свободной для использования действием, панель инструментов перемещается вверх, чтобы занять это пространство. Чтобы это исправить, вам нужно вручную переместить панель инструментов в исходное место.
Добавьте следующие теги в представление "android.support.v7.Widget.Toolbar":
android:layout_height="48dp" // Whatever the height of the toolbar you want
android:layout_marginTop="-48dp" // Negative of the height of the toolbar
Расширить CoordinatorLayout
и позвонить setOnApplyWindowInsetsListener
в вашем конструкторе для сброса значений вставки. Вот код:
public class CustomCoordinatorLayout extends CoordinatorLayout {
public CustomCoordinatorLayout(Context context) {
super(context);
init();
}
public CustomCoordinatorLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
WindowInsets replaced = windowInsets.replaceSystemWindowInsets(0, 0, 0, 0);
return replaced;
}
});
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
У меня та же проблема, но есть одна вещь, которую я знаю.
Если вам нужна прозрачная строка состояния на обычной панели инструментов, вам нужно добавить верхнюю часть отступа 16dp.
Просто измените цвет строки состояния в Styles.XML(v21)
<item name="android:statusBarColor">@android:color/transparent</item>
или удалите вышеприведенную строку в этом XML, он отлично работает.