139 votes

Est-ce une mauvaise pratique d'utiliser des marges négatives dans Android ?

Démonstration de la marge négative :

                         enter image description here

Le scénario

Chevauchement de vues en définissant une marge négative à l'une d'entre elles de manière à ce qu'elle envahisse la boîte englobante d'une autre vue.

Pensées

Cela semble fonctionner comme prévu, avec un chevauchement des mises en page si nécessaire. Mais je ne veux pas me heurter à un problème plus important en ne faisant pas les choses correctement sans le savoir. Emulateurs, périphériques physiques, etc., lorsque vous utilisez des marges négatives, tout semble fonctionner correctement, une vue envahit la boîte de délimitation d'une autre vue et, selon la façon dont elle est déclarée dans la mise en page, elle sera au-dessus ou au-dessous de l'autre vue.

Je suis également conscient que depuis l'API 21, nous pouvons définir l'option translationZ y elevation attributs pour faire apparaître la vue au-dessus ou au-dessous des autres vues mais ma préoccupation vient essentiellement du fait que dans la documentation pour le layout_margin attributs il est clairement spécifié que les valeurs de marge doivent être positives Laissez-moi vous citer :

Extrait :
Spécifie un espace supplémentaire sur les côtés gauche, supérieur, droit et inférieur de cette vue. Cet espace est en dehors des limites de cette vue. Les valeurs des marges doivent être positives . Doit être une valeur de dimension, qui est un nombre à virgule flottante auquel est ajoutée une unité telle que "14.5sp". Les unités disponibles sont : px (pixels), dp (pixels indépendants de la densité), sp (pixels mis à l'échelle en fonction de la taille de police préférée), in (pouces), mm (millimètres)...

Depuis que j'ai posé cette question, je n'ai eu aucun problème avec les marges négatives, j'ai essayé d'éviter de les utiliser autant que possible, mais j'ai pas Je n'ai rencontré aucun problème, donc même si la documentation l'indique, je ne suis pas trop inquiet à ce sujet.

2 votes

Je sais que les tests espresso ne seront pas capables de voir l'objet si l'une de ses marges est négative... c'est donc une raison pour ne pas les utiliser.

216voto

CommonsWare Points 402670

En 2010, @RomainGuy (ingénieur principal d'Android) a déclaré que les marges négatives ont eu un comportement non spécifié .

En 2011, @RomainGuy a déclaré que vous pouvez utiliser des marges négatives sur LinearLayout y RelativeLayout .

En 2016, @RomainGuy a déclaré que ils n'ont jamais été officiellement pris en charge et ne le seront pas par la Commission européenne. ConstraintLayout .

Il est cependant facile de contourner cette limitation.

Ajoutez une vue auxiliaire (hauteur 0dp, largeur contrainte au parent) au bas de votre vue de base, au bas ajoutez la marge que vous voulez.
Positionnez ensuite votre vue en dessous de celle-ci, en lui permettant effectivement d'avoir une marge "négative", mais sans avoir à utiliser une valeur négative non soutenue.

1 votes

Il semble que ce soit une chose inoffensive alors, je laisse ouvert au cas où quelqu'un aurait d'autres idées.

0 votes

Je suppose qu'il en va de même pour les paddings négatifs

2 votes

@DrewLeSueur : Je ne ferais pas cette supposition. Je n'ai aucune idée de ce qu'un rembourrage négatif pourrait même signifier.

27voto

VicJordan Points 382

J'espère que cela aidera quelqu'un. Voici un exemple de code fonctionnel utilisant ConstraintLayout sur la base de la réponse de @CommonsWare :

Ajoutez une vue auxiliaire (hauteur 0dp, largeur limitée au parent) à l'endroit où se trouve l'icône en bas de votre vue de base, et ajoutez la marge que vous voulez. Ensuite, positionnez votre vue sous celle-ci, lui permettant ainsi d'avoir une marge marge "négative", mais sans avoir à utiliser une valeur négative non prise en charge. négative.

Exemple de code :

<TextView
    android:id="@+id/below"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#F1B36D"
    android:padding="30dp"
    android:text="I'm below"
    android:textColor="#ffffff"
    android:textSize="48sp"
    android:textAlignment="center"
    tools:layout_editor_absoluteX="129dp"
    tools:layout_editor_absoluteY="0dp" />

<android.support.v4.widget.Space
    android:id="@+id/space"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginBottom="32dp"
    app:layout_constraintBottom_toBottomOf="@+id/below"
    app:layout_constraintLeft_toLeftOf="@id/below"
    app:layout_constraintRight_toRightOf="@id/below" />

<TextView
    android:id="@+id/top"
    android:layout_width="100dp"
    android:layout_height="60dp"
    android:textAlignment="center"
    android:textColor="#ffffff"
    android:text="I'M ON TOP!"
    android:background="#676563"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/space" />

Sortie :

enter image description here

20voto

I.Step Points 105

Au lieu de marges négatives, vous pouvez utiliser : translationX y translationY .

Exemple :

android:layout_marginBottom = -2dp

android:translationY = -2dp

UPDATE : Gardez à l'esprit que la vue entière est traduite.

17voto

Ali Points 1597

Si vous souhaitez utiliser une marge négative, définissez une marge suffisante pour le conteneur et ses éléments. clipToPadding à false et définit une marge négative pour ses enfants afin de ne pas couper la vue enfant !

5voto

Gábor Points 424

Cela aurait pu être une mauvaise pratique dans le passé, mais avec Material Design et ses boutons d'action flottants, cela semble être inévitable et requis dans de nombreux cas maintenant. En fait, lorsque vous avez deux mises en page distinctes que vous ne pouvez pas intégrer dans un seul RelativeLayout parce qu'elles doivent être traitées séparément (pensez à l'en-tête et au contenu, par exemple), la seule façon de faire chevaucher le FAB est de le faire ressortir de l'une de ces mises en page en utilisant des marges négatives. Et cela crée des problèmes supplémentaires avec les zones cliquables.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X