Diferenças entre ConstraintLayout e RelativeLayout

219

Estou confuso sobre a diferença entre ConstraintLayoute RelativeLayout. Alguém poderia me dizer as diferenças exatas entre eles?

b2mob
fonte
9
O ConstraintLayout é projetado principalmente para os novos programadores, para que eles possam projetar facilmente o layout usando o Editor Visual em vez de criar o layout manualmente via XML.
CopsOnRoad
1
@Jack definitivamente ele também tem um propósito mais profundo para devs-perito experiente
Moses Aprico
@MosesAprico você está certo, ele tem isso. Mas eu acho que devs perito experiente já tem muitas outras maneiras (eles já sabem como RealtiveLayout, LinearLayout, GridLayoutetc.) para obter a hierarquia de vista que eles querem.
CopsOnRoad
5
@CopsOnRoad Na verdade, você está errado. A Apple faz layouts de restrições há mais de 5 anos. Você obtém um design responsivo para qualquer tamanho e não precisa escrever uma tonelada de layouts complexos. Ao iniciar a associação de várias visualizações, você precisa apenas de três controles básicos para criar um design totalmente responsivo.
Nick Turner

Respostas:

145

A intenção de ConstraintLayouté otimizar e nivelar a hierarquia de visualizações de seus layouts aplicando algumas regras a cada visualização para evitar o aninhamento.

As regras lembram RelativeLayout, por exemplo, a configuração da esquerda para a esquerda de alguma outra visualização.

app:layout_constraintBottom_toBottomOf="@+id/view1"

Ao contrário RelativeLayout, ConstraintLayoutoferece um biasvalor usado para posicionar uma vista em termos de 0% e 100% de deslocamento horizontal e vertical em relação às alças (marcadas com círculo). Essas porcentagens (e frações) oferecem posicionamento perfeito da vista em diferentes densidades e tamanhos de tela.

app:layout_constraintHorizontal_bias="0.33" <!-- from 0.0 to 1.0 -->
app:layout_constraintVertical_bias="0.53" <!-- from 0.0 to 1.0 -->

A alça da linha de base (tubo longo com cantos arredondados, abaixo da alça do círculo) é usada para alinhar o conteúdo da vista com outra referência de vista.

Alças quadradas (em cada canto da vista) são usadas para redimensionar a vista em dps.

insira a descrição da imagem aqui

Isso é totalmente baseado em opiniões e minha impressão de ConstraintLayout

Nikola Despotoski
fonte
9
Ainda podemos criar um layout nivelado usando o RelativeLayout, e é por isso que estou confuso quanto ao ConstraintLayout, onde o RelativeLayout não pode?
7
RelativeLayout é um layout de duas passagens, que sofre de dupla tributação. Ele deve medir / layout pelo menos duas vezes. O ConstraintLayout não sofre essa penalidade de desempenho.
Christopher Perry
5
@Nada, ainda podemos criar um layout nivelado usando o RelativeLayout. Mas, além de todos os mencionados aqui, o ConstraintLayout permite usar margens negativas e subvisões de tamanho em uma proporção predefinida . Último é a forma mais robusta para manter formato 16: 9 para o seu ImageView no CardView de acordo com o projeto de materiais
Eugene Brusov
4
Existem alguns layouts impossíveis no RelativeLayout, a menos que você aninhe um LinearLayout ou outro RelativeLayout. Por exemplo: centralizando uma "pilha" de 3 Views verticalmente em relação a outro View
Gak2 20/17
@ Gak2 Não vejo nada impossível no seu exemplo sem um layout aninhado. Talvez você queira dizer algo mais com "pilha" do que eu. Eu apenas uso "layout_alignEnd", "layout_below", "layout _..." e posso construir qualquer tipo de pilha com ele ...
O incrível Jan
81

Propriedades equivalentes de layout relativo e de layout de restrição

Propriedades equivalentes de layout relativo e de layout de restrição

(1) Layout relativo:

android:layout_centerInParent="true"    

(1) Equivalente ao layout da restrição:

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"

(2) Layout relativo:

android:layout_centerHorizontal="true"

(2) Equivalente ao layout da restrição:

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintEnd_toEndOf="parent"

(3) Layout relativo:

android:layout_centerVertical="true"    

(3) Equivalente ao layout da restrição:

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"

(4) Layout relativo:

android:layout_alignParentLeft="true"   

(4) Equivalente ao layout da restrição:

app:layout_constraintLeft_toLeftOf="parent"

(5) Layout relativo:

android:layout_alignParentStart="true"

(5) Equivalente ao layout da restrição:

app:layout_constraintStart_toStartOf="parent"

(6) Layout relativo:

android:layout_alignParentRight="true"

(6) Equivalente ao layout da restrição:

app:layout_constraintRight_toRightOf="parent"

(7) Layout relativo:

android:layout_alignParentEnd="true"    

(7) Equivalente ao layout da restrição:

app:layout_constraintEnd_toEndOf="parent"

(8) Layout relativo:

android:layout_alignParentTop="true"

(8) Equivalente à disposição das restrições:

app:layout_constraintTop_toTopOf="parent"

(9) Layout relativo:

android:layout_alignParentBottom="true" 

(9) Equivalente ao layout da restrição:

app:layout_constraintBottom_toBottomOf="parent"

(10) Layout relativo:

android:layout_alignStart="@id/view"

(10) Equivalente ao layout da restrição:

app:layout_constraintStart_toStartOf="@id/view"

(11) Layout relativo:

android:layout_alignLeft="@id/view" 

(11) Equivalente ao esquema de restrições:

app:layout_constraintLeft_toLeftOf="@id/view"

(12) Layout relativo:

android:layout_alignEnd="@id/view"  

(12) Equivalente ao esquema de restrições:

app:layout_constraintEnd_toEndOf="@id/view"

(13) Layout relativo:

android:layout_alignRight="@id/view"

(13) Equivalente à disposição das restrições:

app:layout_constraintRight_toRightOf="@id/view"

(14) Layout relativo:

android:layout_alignTop="@id/view"  

(14) Equivalente ao esquema de restrições:

app:layout_constraintTop_toTopOf="@id/view"

(15) Layout relativo:

android:layout_alignBaseline="@id/view" 

(15) Equivalente ao esquema de restrições:

app:layout_constraintBaseline_toBaselineOf="@id/view"

(16) Layout relativo:

android:layout_alignBottom="@id/view"

(16) Equivalente ao esquema de restrições:

app:layout_constraintBottom_toBottomOf="@id/view"

(17) Layout relativo:

android:layout_toStartOf="@id/view"

(17) Equivalente ao esquema de restrições:

app:layout_constraintEnd_toStartOf="@id/view"

(18) Layout relativo:

android:layout_toLeftOf="@id/view"  

(18) Equivalente ao esquema de restrições:

app:layout_constraintRight_toLeftOf="@id/view"

(19) Layout relativo:

android:layout_toEndOf="@id/view"

(19) Equivalente ao esquema de restrições:

app:layout_constraintStart_toEndOf="@id/view"

(20) Layout relativo:

android:layout_toRightOf="@id/view"

(20) Equivalente ao esquema de restrições:

app:layout_constraintLeft_toRightOf="@id/view"

(21) Layout relativo:

android:layout_above="@id/view" 

(21) Equivalente ao esquema de restrições:

app:layout_constraintBottom_toTopOf="@id/view"

(22) Layout relativo:

android:layout_below="@id/view" 

(22) Equivalente ao esquema de restrições:

app:layout_constraintTop_toBottomOf="@id/view"

Naimatullah
fonte
2
Você pode postar como texto em vez de imagem? Para que seja muito útil para mim e para outras pessoas no futuro.
Novo desenvolvedor
3
Todo mundo que começa a aprender os Layouts de restrições precisa ver isso. Obrigado.
Granton
1
Esta é uma informação útil, mas é simplesmente um despejo de documentação e não faz nada para explicar a diferença entre eles.
YetAnotherRandomUser
1
Não, não tenho tempo para procurar documentos, isso é certamente útil. E escrito em linguagem simples. Voto a favor.
CodeToLife 20/05/19
46

Reportado por @davidpbr ConstraintLayout performance

Fiz dois layouts de 7 filhos semelhantes, um com pai ConstraintLayoute mãe RelativeLayout. Com base na ferramenta de rastreamento de método do Android Studio, parece que ele ConstraintLayoutpassa mais tempo no onMeasure e executa trabalho adicional no onFinishInflate.

Biblioteca utilizada ( support-v4, appcompat-v7…):

com.android.support.constraint:constraint-layout:1.0.0-alpha1

Dispositivos / versões do Android reproduzidos em: Samsung Galaxy S6 (SM-G920A. Desculpe, não Nexus ATM). Android 5.0.2

Comparação rápida de rastreamento de método:

1

Exemplo de repositório do Github: https://github.com/OnlyInAmerica/ConstraintLayoutPerf

Dhaval Jivani
fonte
do mesmo problema: vou encerrar isso por enquanto - o alpha 4/5 trouxe um pouco de melhoria de desempenho. Provavelmente, poderemos melhorá-lo mais, mas isso pode esperar após a 1.0.
precisa
Você pode explicar em qual ferramenta você usou para criar essa ótima comparação?
Nativ
2
@Nativ Monotirs-> CPU-> Ícone do rastreador de tempo
Andrey T
18
Execute e crie o perfil do mesmo código com o layout de restrição: 1.0.1 no Nexus 5 com o Android 6.0.1, aqui resultados: Layout relativo - init 2ms na Medida 30ms + 16ms = 62ms no Layouyt 7ms = 9ms no total 54 ms Layout de restrição - init Layout de restrição de 7ms gerar parâmetros de layout + adicionar visualização ~ 7 * 2ms = 14ms Na medida 60ms + 52ms ~ 112ms No layout 8ms total ~ 141ms Primeira inicialização do layout relativo quase três vezes mais rápido que o Constraint.
Andrey T
2
O Layout de restrição é introduzido para que a hierarquia de exibição aninhada possa ser reduzida. Portanto, menos hierarquia significa menos tempo para percorrer de cima para baixo na árvore da visualização. Então, qual é o objetivo de criar uma hierarquia de exibição aninhada que pode não ser necessária no layout de restrições e compará-la com o layout relativo, no qual você tem mais chances de terminar com a estrutura aninhada?
codepeaker 13/09/18
27

A seguir estão as diferenças / vantagens:

  1. O Layout de restrição tem poder duplo no Layout relativo e no Linear: defina as posições relativas das visualizações (como o layout relativo) e defina pesos para a interface do usuário dinâmica (que só era possível no layout linear).

  2. Um uso muito poderoso é o agrupamento de elementos, formando uma corrente. Dessa forma, podemos formar um grupo de visões que, como um todo, podem ser colocadas da maneira desejada sem adicionar outra camada de hierarquia apenas para formar outro grupo de visões.

  3. Além dos pesos, podemos aplicar o viés horizontal e vertical, que nada mais é do que a porcentagem de deslocamento do centro. (desvio de 0,5 significa alinhado centralmente. Qualquer valor menor ou mais significa movimento correspondente na respectiva direção).

  4. Outro recurso muito importante é que ele respeita e fornece a funcionalidade para lidar com as visualizações GONE, para que os layouts não sejam quebrados se alguma visualização for definida como GONE através do código java. Mais pode ser encontrado aqui: https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#VisibilityBehavior

  5. Fornece poder de restrição automática aplicada pelo uso da ferramenta Blue print e Visual Editor, que facilita o design de uma página.

Todos esses recursos levam ao achatamento da hierarquia de visualizações, o que melhora o desempenho e também ajuda a criar uma interface de usuário dinâmica e responsiva, que pode se adaptar mais facilmente a diferentes tamanhos e densidades de tela.

Aqui é o melhor lugar para aprender rapidamente: https://codelabs.developers.google.com/codelabs/constraint-layout/#0

Vishu Gupta
fonte
6) O ConstraintLayout permite dimensionar sub - visualizações em proporções predefinidas medium.com/google-developers/… . Seria útil, por exemplo, quando você manterá seu ImageView em 16: 9.
Eugene Brusov 21/09
15

Uma grande diferença é que o ConstraintLayout respeita as restrições, mesmo que a exibição acabe. Portanto, ele não quebrará o layout se você tiver uma corrente e quiser fazer uma exibição desaparecer no meio.

Herrbert74
fonte
você pode me dar um exemplo? vamos supor que 3 botões estejam lá. Vou ocultar o segundo botão e o terceiro botão é anexado ao segundo botão com o ID como btn2. Suponha que eu oculte o segundo botão e como o terceiro botão poderia encontrar a identificação do segundo botão?
1
Isso não é verdade. Se você definir a visibilidade de um botão como "INVISÍVEL" em vez de "GONE", não quebrará as restrições. Quanto a mim, a maior diferença que o @Nikola disse é o viés que ajuda a criar mais visualizações "Responsivas".
Zapotec 04/04
@Nada suponha que os botões estejam embaixo um do outro. Mesmo se você ocultar o botão 2, ele ainda estará lá no "contrato de exibição", no seu xml ou código. O ConstraintLayout o respeitará e o Botão 3 estará sob o Botão 1. Em um RelativeLayout, o Botão 2 se foi, o contraint se foi com ele; portanto, o Botão 3 estará na posição padrão, no canto superior esquerdo da tela.
Herrbert74
@ zapotec Eu respeito que outras coisas são mais importantes para você, mas para mim essa é uma diferença muito legal. Corrige a única coisa que eu odiava no RelativeLayout. Usar invisível não é uma opção, porque reivindicará o espaço.
Herrbert74
7

Além da resposta @ dhaval-jivani.

Atualizei o projeto github do projeto para a versão mais recente do layout de restrição v.1.1.0-beta3

Eu medi e comparei o tempo do método onCreate e o tempo entre o início do onCreate e o final da execução do último método preformDraw, visível no monitor da CPU. Todos os testes foram feitos no Samsung S5 mini com o Android 6.0.1. Resultados aqui:

Novo começo (abertura da primeira tela após o lançamento do aplicativo)

esquema relativo

OnCreate: 123ms

Tempo de desenho - OnCreate: 311.3ms

Layout de restrição

OnCreate: 120.3ms

Tempo de desenho - OnCreate tempo: 310ms

Além disso, verifiquei o teste de desempenho deste artigo , aqui o código e constatou que o loop on conta menos de 100 variantes de layout de restrição são mais rápidas durante a execução de inflar, medir e layout e variantes com layout relativo. E em dispositivos Android antigos, como o Samsung S3 com Android 4.3, a diferença é maior.

Como conclusão, concordo com os comentários do artigo :

Vale a pena refatorar as exibições antigas, ativá-lo de RelativeLayout ou LinearLayout?

Como sempre: depende 🙂

Eu não refatoraria nada, a menos que você tenha um problema de desempenho com sua hierarquia de layout atual ou deseje fazer alterações significativas no layout. Embora eu não tenha medido isso recentemente, não encontrei nenhum problema de desempenho nos últimos lançamentos. Então eu acho que você deve estar seguro para usá-lo. mas - como eu disse - não migre apenas para migrar. Faça isso apenas se houver necessidade e se beneficiar com isso. Para novos layouts, no entanto, quase sempre uso o ConstraintLayout. É muito melhor comparar com o que tínhamos antes.

Andrey T
fonte
6

Oficialmente, ConstraintLayouté muito mais rápido

Na versão N do Android, a ConstraintLayoutclasse fornece funcionalidade semelhante RelativeLayout, mas a um custo significativamente menor.

serv-inc
fonte
6

A verdadeira pergunta a fazer é: existe algum motivo para usar outro layout que não seja um layout de restrição? Eu acredito que a resposta pode ser não.

Para aqueles que insistem que são direcionados a programadores iniciantes ou similares, eles devem fornecer algum motivo para serem inferiores a qualquer outro layout.

Os layouts de restrições são melhores em todos os aspectos (eles custam 150k no tamanho do APK). Eles são mais rápidos, mais fáceis, mais flexíveis, reagem melhor às mudanças, corrigem os problemas quando os itens desaparecem, se adaptam melhor a tipos de tela radicalmente diferentes e não usam um monte de loop aninhado por tanto tempo estrutura de árvore desenhada para tudo. Você pode colocar qualquer coisa em qualquer lugar, com relação a qualquer coisa, em qualquer lugar.

Eles eram um pouco esquisitos em meados de 2016, onde o editor de layout visual simplesmente não era bom o suficiente, mas estão ao ponto de que, se você tiver um layout, poderá considerar seriamente o uso de um layout de restrição, até quando faz a mesma coisa que um RelativeLayout, ou mesmo um simples LinearLayout. FrameLayoutsclaramente ainda tem seu objetivo. Mas não consigo ver a construção de mais nada neste momento. Se eles começassem com isso, não teriam acrescentado mais nada.

Tatarize
fonte
1
Existe alguma prova disso mais rápido?
Rajesh Naşit
1
Sim. É mais rápido. O layout está desativado em um único solucionador, em vez de iterar através de uma árvore. Para a maioria das coisas, isso não importa, porque é feito na chamada para o layout. Porém, a coisa da árvore de visualização, embora fácil, cria várias visualizações dentro das visualizações, o que requer chamadas que exigem chamadas. Embora seja melhor teoricamente, na prática, executar o layout em um bit de código é muito mais fácil do que percorrer toda a árvore de exibição. Ele iria ficar mais impressionante, com mais vistas, mas aqui está um ponto de referência a partir de maio: medium.com/@krpiotrek/constraintlayout-performance-c1455c7984d7
Tatarize
Estou enfrentando outra pergunta, devo substituir todos os Relativelayouts existentes no aplicativo em que estou trabalhando? Melhorará significativamente o desempenho?
Sreekanth Karumanaghat 25/03/19
@SreekanthKaruman, parece que você nunca recuperaria o tempo necessário para substituí-los na troca de tempo que o salvaria. Estamos falando de ciclos de 3,5ms, caindo para 3,25ms na maioria dos casos. Se lhe der um recurso extra ou algo que você precisa, com certeza, mas puramente por motivos de velocidade, nah. Embora estejamos falando, pressione um botão de conversão.
Tatarize 26/03/19
5

A conclusão que posso tirar é

1) Podemos fazer o design da interface do usuário sem tocar na parte xml do código; para ser sincero, sinto que o Google copiou como a interface do usuário é projetada em aplicativos iOS ; faz sentido se você estiver familiarizado com o desenvolvimento da interface no iOS, mas no layout relativo, difícil definir as restrições sem tocar no design xml .

2) Em segundo lugar, possui uma hierarquia de visualização plana diferente de outros layouts, além de um desempenho melhor do que o layout relativo, que você pode ter visto em outras respostas

3) Ele também possui outras coisas além do layout relativo, como o posicionamento relativo circular, onde podemos posicionar outra vista em relação a essa em determinado raio e com determinado ângulo, o que não pode ser feito no layout relativo.

Estou dizendo novamente: projetar interface do usuário usando o layout de restrição é o mesmo que projetar interface do usuário no iOS; portanto, no futuro, se você trabalhar no iOS, será mais fácil se tiver usado o layout de restrição

murali krish
fonte
1

A única diferença que notei é que as coisas definidas em um layout relativo via arrastar e soltar automaticamente têm suas dimensões em relação a outros elementos inferidos; portanto, quando você executa o aplicativo, o que vê é o que obtém. No entanto, no layout da restrição, mesmo que você arraste e solte um elemento na exibição de design, quando você executa o aplicativo, as coisas podem mudar. Isso pode ser facilmente corrigido definindo manualmente as restrições ou, uma ação mais arriscada é clicar com o botão direito do mouse no elemento na árvore de componentes, selecionar o submenu de layout de restrição e clicar em 'inferir restrições'. Espero que isto ajude

Wilson
fonte