web-dev-qa-db-fra.com

Tiroir de navigation Android et windowActionBarOverlay = true

J'essaie d'implémenter le nouveau tiroir de navigation Android dans mon application. J'ai créé un BaseActivity.Java qui gère la configuration du tiroir et les écouteurs, et j'ai deux sous-activités qui étendent cette classe de base. Lors de la deuxième activité, je prévois d'utiliser un style de barre d'action différent, en utilisant les attributs suivants:

<item name="Android:windowActionBarOverlay">true</item>
<item name="Android:background">@Android:color/transparent</item>

rendre la barre d’action transparente et rendre le contenu plus riche, car il y a un en-tête d’image dans ma mise en page. 

Je viens de réaliser cela, mais le problème est que, comme le contenu est en train de s’étendre pour tirer parti de l’espace supplémentaire que représente l’utilisation de la barre d’action en tant que superposition, le tiroir de navigation lui-même s’agrandit également et chevauche celle-ci, créant ainsi mise en page: 

enter image description here

Ce que j'aurais aimé faire, c’est le contenu réel (la disposition du cadre qui sera remplie d’un fragment) pour occuper l’espace supplémentaire, mais laissez le tiroir de navigation toujours sous la barre d’action, comme dans l’application Play Music: 

enter image description here

Des idées sur ce que je peux faire pour y arriver? 

EDIT Ainsi, conformément à l'aide d'Ahmad, je règle la marginTop sur le ListView uniquement. Voici la mise en page: 

<!-- The navigation drawer -->
<ListView Android:id="@+id/left_drawer"
          Android:layout_marginTop="?android:attr/actionBarSize"
<!-- This was added after seeing the crazy effect, but does nothing -->
          Android:layout_marginBottom="0dp"
          Android:layout_marginLeft="0dp"
          Android:layout_marginRight="0dp"
          Android:layout_width="240dp"
          Android:layout_height="fill_parent"
          Android:layout_gravity="start"
          Android:choiceMode="singleChoice"
          Android:background="?attr/listviewBackground"
          />

Et maintenant, cela fonctionne très bien pour la face supérieure, mais pour une raison quelconque, il y a aussi une marge au bas de la vue, ce qui n'a aucun sens pour moi. Voici une capture d'écran

Pas sûr de ce qui le cause :(

25
daniel_c05

Si quelqu'un est intéressé par une autre réponse à cette question. Voici ce qui s'est passé. 

J'ai essayé de définir uniquement la marge en haut de la liste, comme suit: 

Android:layout_marginTop="?android:attr/actionBarSize"

Mais comme mentionné dans la question modifiée, le comportement était étrange et il existait également une marge en bas bien que le fichier de ressources de mise en page ne soit pas défini. 

Je regardais donc de près l’application Play Music et remarquai qu’il ne s’agissait pas d’une marge, mais plutôt d’un remplissage, et qu’ils utilisaient en outre un arrière-plan personnalisé remplissant l’espace spécifié par le remplissage d’une couleur transparente. 

Voici ce que j'ai fait: 

  • Placez Padding en haut de ListView, plutôt que de la marge: 

    Android:paddingTop="?android:attr/actionBarSize"

Comme indiqué précédemment, il est important de ne pas coder en dur les dimensions car elles varient d’un périphérique à l’autre. 

  • Créez un dessin personnalisable dont la partie supérieure est transparente, puis restez d'une couleur unie: 

Cela ressemble en quelque sorte à ceci: 

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<item>
    <shape  Android:shape="rectangle">
        <solid Android:color="#80000000" />
    </shape>
</item>

<item Android:top="@dimen/action_bar_default_height">
    <shape
            Android:shape="rectangle">
        <solid Android:color="@color/light_gray" />
    </shape>
</item>

Notez que j'ai essayé d'utiliser ?android:attr/actionBarSize sur le dessinable, mais cela a forcé l'application à se fermer. Au lieu de cela, j'ai effectué une recherche dans grepcode et trouvé quelques fichiers dimen avec des tailles différentes pour la barre d'action. J'ai donc ajouté ceux-ci aux fichiers dimen de mon propre projet. 

  • Pour les valeurs: 48dp
  • Pour value-land: 40dp
  • Pour les valeurs sw600dp: 56dp

Et après cela, je trouve que je suis superbe, remarquez sur la capture d'écran que la liste et la barre d’action ne se chevauchent pas, et que la partie transparente de la liste est exactement à la bonne taille. 

enter image description here

J'espère que cela aidera tous ceux qui se demandaient comment y parvenir. 

14
daniel_c05

Et maintenant, cela fonctionne très bien pour le haut, mais pour une raison quelconque, il y a aussi une marge en bas de la vue, ce qui n'a aucun sens pour moi. Voici une capture d'écran.

Si vous réglez la gravité de ListView sur start | bottom , cela résout votre problème. Aucune marge supplémentaire n'est ajoutée en bas. On dirait que la gravité par défaut DrawerLayout est start | center

<ListView
    Android:id="@+id/left_drawer"
    Android:layout_marginTop="?android:attr/actionBarSize"
    Android:layout_width="240dp"
    Android:layout_height="match_parent"
    Android:layout_gravity="start|bottom"/>
17
kofi

Vous pouvez définir une marge en haut de votre mise en page, de sorte que le contenu se dessine sous le ActionBar. 

Ajoutez simplement ceci dans votre mise en page parent:

Android:layout_marginTop="?android:attr/actionBarSize"

L'attribut actionBarSize fait référence, comme vous l'avez déjà deviné, à la taille de la ActionBar. Vous ne pouvez pas définir une valeur absolue comme marge, car la ActionBar n'a pas toujours la même taille sur tous les appareils Android (plus grande sur les tablettes, plus petite sur les combinés). 

Modifier:

Définissez la marge sur ListView.

<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <FrameLayout
        Android:id="@+id/content_frame"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

    <ListView
        Android:id="@+id/left_drawer"
        Android:layout_marginTop="?android:attr/actionBarSize"
        Android:layout_width="240dp"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"/>
</Android.support.v4.widget.DrawerLayout>

L'application Google Musique fait la même chose:

enter image description here

8
Ahmad

J'ai résolu ce problème en utilisant paddingTop :

<FrameLayout
    Android:id="@+id/menu_frame"
    Android:layout_width="240dp"
    Android:layout_height="match_parent"
    Android:layout_gravity="start"
    Android:paddingTop="?attr/actionBarSize" >

    <ListView 
        Android:id="@+id/left_drawer_list"
        Android:layout_width="240dp"
        Android:layout_height="match_parent" />

</FrameLayout>

J'espère que cela pourra aider

4
Vadim Bryl

J'ai créé une démonstration fonctionnante en suivant le guide ci-dessus et testé sur les versions 2.x à 5.x 

Vous pouvez cloner depuis Github

La chose importante à jouer est dans l'activité principale 

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    res = this.getResources();

    this.setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setHomeButtonEnabled(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop)
    { 
        ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout)
                findViewById(R.id.linearLayout);
        scrimInsetsFrameLayout.setOnInsetsCallback(this);
    } 

et le rappel 

@Override
public void onInsetsChanged(Rect insets) {
      Toolbar toolbar = this.toolbar;
        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
                toolbar.getLayoutParams();
        lp.topMargin = insets.top;
        int top = insets.top;
        insets.top += toolbar.getHeight();
        toolbar.setLayoutParams(lp);
        insets.top = top; // revert
}

Absolument le thème de la V21 fait la magie 

 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

    <!-- API 21 theme customizations can go here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/accent_material_light</item>
    <item name="windowActionModeOverlay">true</item>
    <item name="Android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="Android:statusBarColor">@Android:color/transparent</item>
    <item name="Android:windowTranslucentStatus">true</item>
</style>
0
Vipin Sahu