Definindo a ordem Z de visualizações do RelativeLayout no Android


226

Gostaria de definir a ordem z das visualizações de um RelativeLayout no Android.

Eu sei que uma maneira de fazer isso é chamar bringToFront.

Existe melhor maneira de fazer isso? Seria ótimo se eu pudesse definir a ordem z no xml do layout.


4
View.bringToFront (); é o anser
Shirish Herwade

Respostas:


314

A maneira mais fácil é simplesmente prestar atenção à ordem em que as Views são adicionadas ao seu arquivo XML. Mais abaixo no arquivo significa mais alto no eixo Z.

Editar: está documentado aqui e aqui no site do desenvolvedor do Android. (Obrigado @flightplanner)


16
Infelizmente, isso nem sempre é possível mudar. Por exemplo, em um layout relativo, cada elemento só pode ser disposto com relação aos definidos anteriormente no arquivo
Casebash

67
Casebash, não acho que seja o caso necessário, basta usar o "@ + id / your_element_before_its_defined" e depois usar o mesmo ID no elemento que você definir mais tarde. Posso estar errado sobre isso, esses layouts são muito complicados para mim, mas definitivamente tenho a impressão de que funciona.
tjb

7
tjb está certo (e estou feliz que ele esteja). Use @ + id com a primeira menção da id por exemplo layout_above = "@ + id / some_id"
Michiel

3
Você também pode colocar <item type = "id" name = "<your_id>" /> em um arquivo xml de valores e, em seguida, pode referenciá-lo em qualquer lugar.
karl

8
Eu sei que estou prestes 3 anos atrasado para a festa, mas em resposta a @hpique, isso está documentado aqui
HexAndBugs


68

Observe que os botões e outros elementos na API 21 ou superior têm uma elevação alta e, portanto, ignoram a ordem xml dos elementos, independentemente do layout pai. Levei um tempo para descobrir isso.


16
a solução para esse bug para mim foi chamar setElevation (1000) na exibição que eu quero que seja renderizada sobre o botão.
fogo no buraco

setElevation () requer API nível 21
dp2050 11/03

21

No Android, a partir do nível 21 da API, os itens no arquivo de layout obtêm sua ordem Z, tanto na forma como são ordenados no arquivo, conforme descrito na resposta correta, quanto na elevação, um valor de elevação mais alto significa que o item recebe uma ordem Z mais alta .

Às vezes, isso pode causar problemas, especialmente com botões que geralmente aparecem em cima de itens que, de acordo com a ordem do XML, devem estar abaixo deles na ordem Z. Para corrigir isso, defina os android:elevationitens no XML do layout para corresponder à ordem Z que você deseja atingir.

Se você definir uma elevação de um elemento no layout, ele começará a projetar uma sombra. Se você não deseja esse efeito, pode remover a sombra com o código da seguinte forma:

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

Não encontrei nenhuma maneira de remover a sombra de uma visualização elevada através do xml de layout.


1
Como mencionado nos comentários, você pode usar android:elevation="1000dp". Nenhuma sombra é renderizada dessa maneira.
Vadim Kotov

15

Encontrei os mesmos problemas: Em um layout relativo parentView, tenho 2 filhos childView1 e childView2. Inicialmente, coloquei childView1 acima de childView2 e quero que childView1 esteja no topo de childView2. Alterar a ordem dos pontos de vista das crianças não resolveu o problema para mim. O que funcionou para mim é definir android: clipChildren = "false" no parentView e no código que defini:

childView1.bringToFront();

parentView.invalidate();

2
Isso está funcionando, e o Android me deixa tão triste. child.bringToFront()com parent.invalidate()obras, mas parent.bringChildToFront(child)não. Onde está a lógica que todos esperamos de um sistema operacional?
Oliver Hausler

Para animar algumas visualizações (traduções em X e Y), tentei várias combinações para LinearLayout, FrameLayout e RelativeLayout, mas sempre havia problemas (relacionados a sobreposições ou tamanhos não proporcionais). Finalmente android:clipChildren="false"fiz o truque. Obrigado!
JCarlosR

15

Observe que você pode usar a view.setZ(float)partir do nível 21. da API. Aqui você pode encontrar mais informações.


13

Pensei em acrescentar uma resposta desde a introdução do

android: translationZ

O campo XML mudou um pouco as coisas. As outras respostas que sugerem execução

childView1.bringToFront();

parentView.invalidate();

estão totalmente no EXCEPT, pois esse código NÃO colocará childView1 na frente de qualquer visualização com um android: translationZ codificado no arquivo XML. Eu estava tendo problemas com isso e, depois que removi esse campo dos outros modos de exibição, bringToFront () funcionou bem.


Isto também é verdade para os android 5 deelevation
shelll

5

API 21 tem view.setElevation(float)build-in

Use ViewCompat.setElevation(view, float);para compatibilidade com versões anteriores

Mais métodos ViewCompat.setZ(v, pixels)eViewCompat.setTranslationZ(v, pixels)

Outra maneira de coletar botões ou exibir a matriz e usar addViewpara adicionar ao RelativeLayout




0

Verifique se você tem alguma elevação em uma das vistas em XML. Nesse caso, adicione elevação ao outro item ou remova a elevação para resolver o problema. A partir daí, é a ordem dos pontos de vista que determina o que vem acima do outro.


0

Ou coloque o botão ou as vistas sobrepostas dentro de um FrameLayout. Em seguida, o RelativeLayout no arquivo xml respeitará a ordem dos layouts filhos à medida que forem adicionados.


0

Você pode usar o exemplo de código abaixo também para obter o mesmo

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

Isso é compatível com versões anteriores. Aqui mCardViewestá uma visão que deve estar abaixo sourceView.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.