Definición del orden Z de vistas de RelativeLayout en Android


226

Me gustaría definir el orden z de las vistas de un RelativeLayout en Android.

Sé que una forma de hacer esto es llamar bringToFront.

¿Hay alguna forma mejor de hacer esto? Sería genial si pudiera definir el orden z en el diseño xml.


44
View.bringToFront (); is the anser
Shirish Herwade

Respuestas:


314

La forma más fácil es simplemente prestar atención al orden en que se agregan las Vistas a su archivo XML. Más abajo en el archivo significa más arriba en el eje Z.

Editar: Esto está documentado aquí y aquí en el sitio para desarrolladores de Android. (Gracias @flightplanner)


16
Desafortunadamente, esto no siempre es posible cambiar. Por ejemplo, en un diseño relativo, cada elemento solo se puede distribuir con respecto a los definidos previamente en el archivo
Casebash

67
Casebash, no creo que sea necesariamente el caso, solo tiene que usar el "@ + id / your_element_before_its_defined" y luego usar el mismo id en el elemento que defina más adelante. Podría estar equivocado sobre esto, estos diseños son muy difíciles para mí, pero definitivamente tengo la impresión de que funciona.
tjb

77
tjb tiene razón (y me alegro de que lo sea). Use @ + id con la primera mención de la identificación, por ejemplo, layout_above = "@ + id / some_id"
Michiel

3
También puede poner <item type = "id" name = "<your_id>" /> en un archivo xml de valores, y luego puede hacer referencia a él en cualquier lugar.
karl

8
Sé que llego 3 años tarde a la fiesta, pero en respuesta a @hpique, esto está documentado aquí
HexAndBugs


68

Tenga en cuenta que los botones y otros elementos en API 21 y superiores tienen una elevación elevada y, por lo tanto, ignoran el orden xml de los elementos independientemente del diseño principal. Me tomó un tiempo entender eso.


16
La solución a este error para mí fue llamar a setElevation (1000) en la vista que quiero que se muestre sobre el botón.
fuego en el hoyo

setElevation () requiere API nivel 21
dp2050

21

En Android a partir del nivel 21 de API, los elementos en el archivo de diseño obtienen su orden Z tanto de cómo se ordenan dentro del archivo, como se describe en la respuesta correcta, como de su elevación, un valor de elevación más alto significa que el elemento obtiene un orden Z más alto .

Esto a veces puede causar problemas, especialmente con botones que a menudo aparecen en la parte superior de los elementos que de acuerdo con el orden del XML deben estar debajo de ellos en el orden Z. Para solucionar esto, configure los android:elevationelementos en su XML de diseño para que coincidan con el orden Z que desea lograr.

Si establece una elevación de un elemento en el diseño, comenzará a proyectar una sombra. Si no desea este efecto, puede eliminar la sombra con un código como este:

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

No he encontrado ninguna forma de eliminar la sombra de una vista elevada a través del diseño xml.


1
Como se menciona en los comentarios, puede usar android:elevation="1000dp". Ninguna sombra se representa de esta manera.
Vadim Kotov

15

Encontré los mismos problemas: en un diseño relativo parentView, tengo 2 hijos childView1 y childView2. Al principio, puse childView1 sobre childView2 y quiero que childView1 esté encima de childView2. Cambiar el orden de las opiniones de los niños no resolvió el problema para mí. Lo que funcionó para mí es configurar android: clipChildren = "false" en parentView y en el código que configuré:

childView1.bringToFront();

parentView.invalidate();

2
Esto está funcionando, y Android me pone muy triste. child.bringToFront()con parent.invalidate()obras, pero parent.bringChildToFront(child)no. ¿Dónde está la lógica que todos esperamos de un sistema operativo?
Oliver Hausler

Para animar algunas vistas (traducciones en X e Y), probé varias combinaciones para LinearLayout, FrameLayout y RelativeLayout pero siempre hubo problemas (relacionados con superposiciones o tamaños no proporcionales). Finalmente android:clipChildren="false"hizo el truco. ¡Gracias!
JCarlosR

15

Tenga en cuenta que puede usar a view.setZ(float)partir del nivel 21 de API. Aquí puede encontrar más información.


13

Pensé que agregaría una respuesta desde la introducción de la

android: translationZ

El campo XML cambió las cosas un poco. Las otras respuestas que sugieren correr

childView1.bringToFront();

parentView.invalidate();

están totalmente en EXCEPTO porque este código NO traerá childView1 delante de ninguna vista con un Android codificado: translationZ en el archivo XML. Estaba teniendo problemas con esto, y una vez que eliminé este campo de las otras vistas, bringToFront () funcionó bien.


Esto también es cierto para los Android 5'selevation
shelll

5

API 21 tiene view.setElevation(float)incorporado

Usar ViewCompat.setElevation(view, float);para compatibilidad con versiones anteriores

Más métodos ViewCompat.setZ(v, pixels)yViewCompat.setTranslationZ(v, pixels)

Otra forma de recopilar botones o ver la matriz y usar addViewpara agregar a RelativeLayout




0

Compruebe si tiene alguna elevación en una de las Vistas en XML. Si es así, agregue elevación al otro elemento o elimine la elevación para resolver el problema. A partir de ahí, es el orden de las vistas lo que dicta lo que está por encima del otro.


0

O coloque el botón o las vistas superpuestas dentro de un FrameLayout. Luego, RelativeLayout en el archivo xml respetará el orden de los diseños secundarios a medida que se agregan.


0

Puede usar el siguiente ejemplo de código también para lograr lo mismo

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

Esto es compatible con versiones anteriores. Aquí mCardViewhay una vista que debería estar debajo sourceView.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.