web-dev-qa-db-fra.com

CoordinatorLayout ne dessine pas derrière la barre d'état, même avec windowTranslucentStatus et fitsSystemWindows

J'essaie de dessiner des vues derrière la barre d'état comme ceci: Desired result

J'ai essayé de produire cet effet avec les techniques recommandées, mais j'obtiens ceci:

Actual result

Il est clair d'après la capture d'écran qu'aucun contenu de mon application n'est dessiné derrière la barre d'état.

Ce qui est intéressant, c'est que le Nav Drawer parvient à dessiner derrière la barre d'état:

enter image description here

Choses que j'ai faites:

  • Utilisez les widgets de la bibliothèque de support - CoordinatorLayout, AppBarLayout, Toolbar, DrawerLayout
  • windowTranslucentStatus défini sur true dans le thème de mon application
  • fitsSystemWindows défini sur true sur mon CoordinatorLayout

Voici le thème de mon application:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <!-- Customize your theme here. -->
  <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@Android:color/transparent</item>
    <item name="colorAccent">@color/colorAccent</item>

    <item name="Android:windowTranslucentStatus">true</item>
</style>

Voici ma structure d'activité:

<Android.support.v4.widget.DrawerLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <FrameLayout Android:id="@+id/page_container"
                 Android:layout_width="match_parent"
                 Android:layout_height="match_parent"
                 Android:fitsSystemWindows="true"/>

    <Android.support.design.widget.NavigationView
        Android:id="@+id/nav_view"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</Android.support.v4.widget.DrawerLayout>

Le FrameLayout dans ma disposition d'activité est remplacé par cette disposition de fragment:

<Android.support.design.widget.CoordinatorLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <FrameLayout Android:layout_width="match_parent"
                 Android:layout_height="match_parent"
                 Android:paddingLeft="@dimen/activity_horizontal_margin"
                 Android:paddingRight="@dimen/activity_horizontal_margin"
                 Android:paddingTop="@dimen/activity_vertical_margin"
                 Android:paddingBottom="@dimen/activity_vertical_margin"
                 Android:background="@Android:color/holo_blue_bright"
                 tools:context=".MainActivity">

        <TextView Android:text="@string/lorem_ipsum"
                  Android:layout_width="wrap_content"
                  Android:layout_height="wrap_content" />
    </FrameLayout>

    <Android.support.design.widget.AppBarLayout
        Android:layout_height="wrap_content"
        Android:layout_width="match_parent"
        app:elevation="0dp"
        Android:theme="@style/AppTheme.TransparentAppBar">

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="@Android:color/transparent"
            app:title="@string/hello_blank_fragment"
            app:popupTheme="@style/AppTheme.OverflowMenu" />

    </Android.support.design.widget.AppBarLayout>

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="bottom|end"
        Android:layout_margin="@dimen/fab_margin"
        Android:src="@Android:drawable/ic_dialog_email" />

</Android.support.design.widget.CoordinatorLayout>
25
Joshua

modifier pour les futurs lecteurs: il y a beaucoup de bonnes informations sur le sujet et le problème dans les commentaires aussi, assurez-vous de les lire.

réponse originale: Votre thème est faux, c'est pourquoi. Malheureusement, il existe des différences sur la façon d'activer dans KitKat ou Lollipop. Sur mon code je l'ai fait en Java, mais vous pouvez aussi le réaliser en XML si vous voulez jouer avec les dossiers V21 De votre arborescence de ressources. Le nom des paramètres sera très similaire aux équivalents Java.

Supprimez le Android:windowTranslucentStatus De votre XML et dans Java utilisez comme ça:

   public static void setTranslucentStatusBar(Window window) {
      if (window == null) return;
      int sdkInt = Build.VERSION.SDK_INT;
      if (sdkInt >= Build.VERSION_CODES.Lollipop) {
         setTranslucentStatusBarLollipop(window);
      } else if (sdkInt >= Build.VERSION_CODES.KitKat) {
         setTranslucentStatusBarKiKat(window);
      }
   }

  @TargetApi(Build.VERSION_CODES.Lollipop)
   private static void setTranslucentStatusBarLollipop(Window window) {
      window.setStatusBarColor(
             window.getContext()
                   .getResources()
                   .getColor(R.color. / add here your translucent color code /));
   }

   @TargetApi(Build.VERSION_CODES.KitKat)
   private static void setTranslucentStatusBarKiKat(Window window) {
      window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
   }

alors vous pouvez appeler depuis votre activité setTranslucentStatusBar(getWindow());

modifier:

rendre la barre d'état translucide et la dessiner derrière elle (pour une raison que je ne comprends pas) sont deux tâches distinctes dans Android.

J'ai regardé plus sur mon code et je suis sûr d'avoir BEAUCOUP plus de Android:fitsSystemWindows="true" Sur ma mise en page que juste le CoordinatorLayout.

voici toutes les vues de ma mise en page avec Android:fitsSystemWindows="true" dessus:

  • Coordonnateur
  • AppBarLayout
  • CollapsingToolbarLayout
  • ImageView (avec l'image d'arrière-plan)
  • FrameLayout (avec le contenu de l'en-tête)

donc ma suggestion est de simplement tester/essayer de remplir Android:fitsSystemWindows="true" sur votre XML.

28
Budius
  1. Si je veux tirer derrière StatusBar J'utilise CoordinatorLayout as la plupart des vues parentales d'activité (Android: fitsSystemWindows = "false")

styles.xml (v21)

<style name="MyTheme.NoActionBar.TransparentStatusBar">
        <item name="Android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="Android:statusBarColor">@Android:color/transparent</item>
        <item name="Android:windowTranslucentStatus">true</item>
    </style>

Ensuite, si vous souhaitez modifier la couleur de la statubarc, vous devez supprimer TRANSLUENT_FLAG comme ceci

Window window = activity().getWindow();
        if(showTransluent){
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(Color.TRANSPARENT);
        }else {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(ContextCompat.getColor(activity(), R.color.colorPrimaryDark));
        }
  1. Si je veux que StatusBar soit translucide et éloigne simultanément la vue de la dissimulation derrière StatusBar, j'utilise la plupart des vues parent FrameLayout avec argument

Mes styles.xml (v21) ressemblent

<resources>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="Android:windowDrawsSystemBarBackgrounds">true</item>
    </style>

    <style name="AppTheme.NoStatusBar" parent="AppTheme.NoActionBar">
        <item name="Android:windowTranslucentStatus">true</item>
        <item name="Android:windowTranslucentNavigation">true</item>
        <item name="windowActionBarOverlay">true</item>
        <item name="Android:windowActionBarOverlay">true</item>
    </style>
</resources>

Et styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

Peut-être que la clé du point ici est d'être sûr que vous utilisez AppCompactActivity ainsi que vous utilisez Theme.AppCompact comme racine pour vos styles.

0
murt

C'était vraiment déroutant pour moi, mais je l'ai finalement compris pour ma combinaison de vues qui ressemble à ceci:

<Android.support.v4.widget.SwipeRefreshLayout - **no fitsSystemWindow set**

<Android.support.design.widget.CoordinatorLayout- Android:fitsSystemWindows="true"

<Android.support.design.widget.AppBarLayout - Android:fitsSystemWindows="true"

<Android.support.design.widget.CollapsingToolbarLayout - Android:fitsSystemWindows="true"

<RelativeLayout - Android:fitsSystemWindows="true"

<ImageView - Android:fitsSystemWindows="true"

J'ai également utilisé les méthodes publiées par Budius dans mon application pour faire fonctionner la barre d'état transparente:

Supprimez Android: windowTranslucentStatus de votre XML et dans Java utilisez comme ça:

   public static void setTranslucentStatusBar(Window window) {
      if (window == null) return;
      int sdkInt = Build.VERSION.SDK_INT;
      if (sdkInt >= Build.VERSION_CODES.Lollipop) {
         setTranslucentStatusBarLollipop(window);
      } else if (sdkInt >= Build.VERSION_CODES.KitKat) {
         setTranslucentStatusBarKiKat(window);
      }
   }

  @TargetApi(Build.VERSION_CODES.Lollipop)
   private static void setTranslucentStatusBarLollipop(Window window) {
      window.setStatusBarColor(
             window.getContext()
                   .getResources()
                   .getColor(R.color. / add here your translucent color code /));
   }

   @TargetApi(Build.VERSION_CODES.KitKat)
   private static void setTranslucentStatusBarKiKat(Window window) {
      window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
   }
0
Simon