web-dev-qa-db-fra.com

Utilisation de windowTranslucentStatus avec CollapsingToolbarLayout

J'essaie d'obtenir un effet similaire à ce qui est vu sur Google Play.

J'ai la disposition ci-dessous pour afficher une barre d'outils transparente avec une image derrière. Lorsque l'utilisateur fait défiler, il y a un effet de parallaxe sur la vue d'image lorsqu'elle défile hors de l'écran. La barre d'outils revient à chaque fois que l'utilisateur fait défiler vers le haut, la vue d'image ne revenant que lorsque l'utilisateur arrive en haut de la liste.

Tout cela fonctionne très bien.

<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>

Le problème

Lorsque je mets true à windowTranslucentStatus. Le contenu de la vue se déplace vers le haut pour se trouver sous la barre d'état, mais le contenu de CollapsingToolbarLayout monte deux fois la hauteur de la barre d'état (CollapsingToolbarLayout conserve la hauteur correcte).

Cela signifie qu'une partie du haut de l'image est coupée et que la barre d'action apparaît maintenant sous la barre d'état au lieu d'en dessous. Comme effet secondaire de cela, il y a maintenant un rembourrage au bas de CollapsingToolbarLayout de la même hauteur que la barre d'état

Voici à quoi cela ressemble sans windowTranslucentStatus. Tout fonctionne bien ici enter image description here

windowTranslucentStatus défini sur true enter image description here

Utilisateur défilant du bas vers le bas dans la liste (pas en haut) enter image description here

32
Stimsoni

Ajoutez fitsSystemWindows à la mise en page et définissez-le sur true.

Mise à jour

Désolé pour ma réponse incomplète. Vous devez ajouter fitsSystemWindows = "true" au format XML comme les codes ci-dessous.

<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>
18
David Jin Han

Il y a maintenant eu une mise à jour de la bibliothèque de conception. Je suppose que le problème signalé ci-dessus était un bug.

Si vous mettez à jour la bibliothèque de conception vers la dernière version, ce problème ne se produit plus.

J'ai maintenant supprimé tous les fitSystemWindows = "true" à l'exception de l'ImageView (car cela doit s'afficher sous la barre d'état).

J'ai également supprimé le remplissage négatif de la barre d'outils.

Ceci est mon thème pour 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>

Tout fonctionne comme prévu maintenant

23
Stimsoni

La meilleure façon d'y parvenir est comme l'a dit Stimsoni

Ajouter Android: fitsSystemWindows = "true" à CoordiatorLayout, AppBarLayout et 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>...
5
mparkes

Une fois que la barre d'état est transparente et libre d'utilisation par l'activité, la barre d'outils est poussée vers le haut pour occuper cet espace. Pour résoudre ce problème, vous devez déplacer manuellement la barre d'outils à l'emplacement d'origine.

Ajoutez les balises ci-dessous à la vue "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
4
Henry

Développez CoordinatorLayout et appelez setOnApplyWindowInsetsListener dans votre constructeur pour réinitialiser les valeurs d'encart. Voici le code:

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);
    }
}
4
Enes

J'ai le même problème, mais il y a une chose que je sais.

Si vous voulez avoir une barre d'état transparente sur une barre d'outils normale, vous devez ajouter un haut de rembourrage 16dp.

2
alvarlagerlof