Définition de l'ordre Z des vues de RelativeLayout dans Android


226

Je voudrais définir l'ordre z des vues d'un RelativeLayout dans Android.

Je sais qu'une façon de le faire est d'appeler bringToFront.

Existe-t-il une meilleure façon de procéder? Ce serait génial si je pouvais définir l'ordre z dans la mise en page xml.


4
View.bringToFront (); est l'anser
Shirish Herwade

Réponses:


314

Le moyen le plus simple consiste simplement à faire attention à l'ordre dans lequel les vues sont ajoutées à votre fichier XML. Plus bas dans le fichier signifie plus haut dans l'axe Z.

Modifier: Ceci est documenté ici et ici sur le site des développeurs Android. (Merci @flightplanner)


16
Ce n'est malheureusement pas toujours possible de changer. Par exemple, dans une disposition relative, chaque élément ne peut être disposé que par rapport à ceux précédemment définis dans le fichier
Casebash

67
Casebash, je ne pense pas que ce soit nécessairement le cas, il vous suffit d'utiliser le "@ + id / your_element_before_its_defined", puis d'utiliser le même identifiant dans l'élément que vous définissez plus tard. Je peux me tromper à ce sujet, ces dispositions sont très difficiles pour moi, mais j'ai vraiment l'impression que cela fonctionne.
tjb

7
tjb a raison (et je suis content qu'il le soit). Utilisez @ + id avec la toute première mention de l'identifiant, par exemple layout_above = "@ + id / some_id"
Michiel

3
Vous pouvez également mettre <item type = "id" name = "<your_id>" /> dans un fichier xml de valeurs, puis vous pouvez le référencer n'importe où.
karl

8
Je sais que j'ai environ 3 ans de retard pour la fête, mais en réponse à @hpique, cela est documenté ici
HexAndBugs

88

Si vous voulez le faire dans le code, vous pouvez le faire

View.bringToFront();

voir les documents


68

Veuillez noter que les boutons et autres éléments de l'API 21 et supérieur ont une élévation élevée et ignorent donc l'ordre xml des éléments, quelle que soit la disposition parent. Cela m'a pris un certain temps pour comprendre celui-là.


16
la solution à ce bogue pour moi a été d'appeler setElevation (1000) sur la vue que je veux voir sur le bouton.
feu dans le trou

setElevation () nécessite le niveau d'API 21
dp2050

21

Dans Android à partir du niveau 21 de l'API, les éléments du fichier de disposition obtiennent leur ordre Z à la fois de la façon dont ils sont ordonnés dans le fichier, comme décrit dans la bonne réponse, et de leur élévation, une valeur d'élévation plus élevée signifie que l'élément obtient un ordre Z plus élevé .

Cela peut parfois causer des problèmes, en particulier avec les boutons qui apparaissent souvent au-dessus des éléments qui, selon l'ordre du XML, doivent être en dessous d'eux dans l'ordre Z. Pour résoudre ce problème, définissez simplement android:elevationles éléments de votre mise en page XML pour qu'ils correspondent à l'ordre Z que vous souhaitez atteindre.

Si vous définissez une élévation d'un élément dans la mise en page, il commencera à projeter une ombre. Si vous ne voulez pas de cet effet, vous pouvez supprimer l'ombre avec du code comme ceci:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   myView.setOutlineProvider(null);
}

Je n'ai trouvé aucun moyen de supprimer l'ombre d'une vue élevée à travers le xml de mise en page.


1
Comme mentionné dans les commentaires, vous pouvez utiliser android:elevation="1000dp". Aucune ombre n'est rendue de cette façon.
Vadim Kotov

15

J'ai rencontré les mêmes problèmes: dans un parentView de disposition relative, j'ai 2 enfants childView1 et childView2. Au début, je mets childView1 au-dessus de childView2 et je veux que childView1 soit au-dessus de childView2. Changer l'ordre des vues des enfants n'a pas résolu le problème pour moi. Ce qui a fonctionné pour moi, c'est de définir android: clipChildren = "false" sur parentView et dans le code que j'ai défini:

childView1.bringToFront();

parentView.invalidate();

2
Cela fonctionne et Android me rend si triste. child.bringToFront()avec des parent.invalidate()œuvres, mais parent.bringChildToFront(child)ne le fait pas. Où est la logique que nous attendons tous d'un OS?
Oliver Hausler

Afin d'animer certaines vues (traductions en X et Y), j'ai essayé plusieurs combinaisons pour LinearLayout, FrameLayout et RelativeLayout mais il y avait toujours des problèmes (liés aux chevauchements ou aux tailles non proportionnelles). Enfin android:clipChildren="false"fait l'affaire. Je vous remercie!
JCarlosR

15

S'il vous plaît noter que vous pouvez utiliser à view.setZ(float)partir du niveau de l' API 21. Ici , vous pouvez trouver plus d' informations.


13

J'ai pensé ajouter une réponse depuis l'introduction du

android: translationZ

Le champ XML a changé les choses un peu. Les autres réponses qui suggèrent de courir

childView1.bringToFront();

parentView.invalidate();

sont totalement parfaits SAUF que ce code ne mettra PAS childView1 devant aucune vue avec un android codé en dur: translationZ dans le fichier XML. J'avais des problèmes avec cela, et une fois que j'ai supprimé ce champ des autres vues, bringToFront () a très bien fonctionné.


cela est également vrai pour les android 5elevation
shelll

5

API 21 a view.setElevation(float)intégré

Utiliser ViewCompat.setElevation(view, float);pour la compatibilité descendante

Plus de méthodes ViewCompat.setZ(v, pixels)etViewCompat.setTranslationZ(v, pixels)

Une autre façon de collecter des boutons ou d'afficher un tableau et de l'utiliser addViewpour ajouter à RelativeLayout




0

Vérifiez si vous avez une élévation sur l'une des vues en XML. Si tel est le cas, ajoutez l'élévation à l'autre élément ou supprimez l'élévation pour résoudre le problème. De là, c'est l'ordre des vues qui dicte ce qui vient au-dessus de l'autre.


0

Ou placez le bouton ou les vues qui se chevauchent dans un FrameLayout. Ensuite, le RelativeLayout dans le fichier xml respectera l'ordre des dispositions enfants lors de leur ajout.


0

Vous pouvez également utiliser l'exemple de code ci-dessous pour obtenir le même

ViewCompat.setElevation(sourceView, ViewCompat.getElevation(mCardView)+1);

Ceci est rétrocompatible. Voici mCardViewune vue qui devrait être ci-dessous sourceView.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.