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

Démo de marge négative:

entrer la description de l'image ici

Le scénario

Superposition de vues en définissant une marge négative sur l’une d’elles pour qu’il envahisse le cadre de sélection d’une autre vue.

Pensées

Cela semble fonctionner comme on pourrait s’y attendre en cas de chevauchement des dispositions, le cas échéant. Mais je ne veux pas rencontrer un problème plus grave pour ne pas faire les choses sans le savoir. Emulateurs, périphériques physiques, vous l’appelez, lorsque vous utilisez des marges négatives, tout semble fonctionner correctement, une vue envahit la boîte englobante d’une autre et, selon la manière dont elle est déclarée dans la présentation, sera supérieure ou inférieure à l’autre.

Je suis également conscient que depuis l’API 21, nous pouvons définir les atsortingbuts translationZ et elevation pour faire apparaître la vue au-dessus ou au-dessous des autres vues, mais mon inquiétude provient du fait que dans la documentation des atsortingbuts layout_margin positif , permettez-moi de 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 de marge doivent être positives . Doit être une valeur de dimension, qui est un nombre à virgule flottante ajouté à 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 basés sur la taille de police préférée), en (pouces), mm (millimètres) …

Dans les années qui ont suivi cette question, je n’ai pas eu de problèmes avec les marges négatives, je n’ai pas essayé de les utiliser autant que possible, mais je n’ai rencontré aucun problème. inquiet à ce sujet.

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

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

En 2016, @RomainGuy a déclaré qu’ils n’ont jamais été officiellement pris en charge et ne seront pas pris en charge par ConstraintLayout .

Cependant, il est facile de contourner cette limitation.

Ajoutez une vue d’assistance (hauteur 0dp, largeur limitée au parent) en bas de votre vue de base, en bas ajoutez la marge souhaitée.
Positionnez ensuite votre vue en dessous de celle-ci, ce qui lui permet d’avoir une marge “négative” mais sans avoir à utiliser de valeur négative non prise en charge.

Si vous souhaitez utiliser une marge négative, définissez suffisamment de remplissage pour le conteneur et son clipToPadding sur false et définissez une marge négative pour ses enfants afin qu’il ne coupe pas la vue enfant!

C’était peut-être une mauvaise pratique dans le passé, mais avec Material Design et ses boutons d’action flottants, cela semble inévitable et nécessaire dans de nombreux cas maintenant. Fondamentalement, lorsque vous avez deux mises en page distinctes que vous ne pouvez pas mettre dans un seul RelativeLayout car elles nécessitent une gestion distincte (par exemple, en-tête et contenu), la seule façon de faire se chevaucher FAB mises en page utilisant des marges négatives. Et cela crée des problèmes supplémentaires avec les zones cliquables.

Pour moi, et en ce qui concerne la définition d’une marge négative sur un TextView (je me rends compte que l’OP fait référence à un ViewGroup, mais je cherchais des problèmes avec des marges négatives et j’ai atterri ici) … API 15) SEULEMENT et le réglage de android:layout_marginTop ou android:layout_marginBottom à une valeur négative telle que -2dp.

Pour certaines raisons, le TextView ne s’affiche pas du tout. Il semble être “disparu” de la vue (pas seulement invisible).

Lorsque j’ai essayé ceci avec les 3 autres versions de layout_margin, je n’ai pas vu le problème.

Notez que je n’ai pas essayé cela sur un périphérique réel, cela utilise un émulateur 4.0.3. C’est la deuxième chose étrange que j’ai trouvée qui n’a affecté que 4.0.3, donc ma nouvelle règle est de toujours tester avec un émulateur 4.0.3 🙂

J’ai réussi à réduire la marge inférieure d’un TextView en utilisant android:lineSpacingExtra="-2dp" qui fonctionne même si j’ai android:singleLine="true" (et donc je n’aurais pas pensé que l’interligne serait un facteur).

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

Ajoutez une vue d’assistance (hauteur 0dp, largeur limitée au parent) en bas de votre vue de base, en bas ajoutez la marge souhaitée. Positionnez ensuite votre vue en dessous de celle-ci, ce qui lui permet d’avoir une marge “négative” mais sans avoir à utiliser de valeur négative non prise en charge.

Exemple de code:

    

Sortie:

entrer la description de l'image ici

Non, vous ne devez pas utiliser de negative margin . Au lieu de cela, vous devriez utiliser translate . Même si les marges négatives fonctionnent parfois, lorsque vous modifiez la mise en page par programmation, traduire vous aidera. Et la vue ne peut pas dépasser l’écran lorsque vous utilisez la marge.

Je sais seulement que c’était possible pour une période assez courte. Mais je ne vois aucun problème avec ça. Soyez simplement conscient des tailles d’écran et faites en sorte de ne pas faire accidentellement des éléments qui ne devraient pas apparaître superposés à l’écran. (c.-à-d. que le texte au-dessus du texte est probablement une mauvaise idée.)