Como fazer o ConstraintLayout funcionar com valores percentuais?


207

Com um Preview 1 do Android Studio 2.2 Google lançou um novo layout em sua biblioteca de suporte: ConstraintLayout. Com o ConstraintLayout, é mais fácil usar uma ferramenta Design no Android Studio, mas não encontrei uma maneira de usar tamanhos relativos (porcentagens ou 'pesos', como no LinearLayout). Existe uma maneira de definir as restrições com base em porcentagens? Por exemplo, fazer uma Visualização ocupar 40% da tela, criar uma margem de 20% entre as visualizações, definir a largura de uma Visualização para 50% da largura de outra Visualização?


3
Suporte percentual para largura ou altura foi adicionado no version 1.1ConstraintLayout. Consulte "Dimensão percentual" em developer.android.com/reference/android/support/constraint/… ou algumas das respostas mais recentes.
sunadorer

Respostas:


225

No momento, você pode fazer isso de duas maneiras.

Uma é criar diretrizes (clique com o botão direito do mouse na área de design e clique em adicionar orientação vertical / horizontal). Você pode clicar no "cabeçalho" da diretriz para alterar o posicionamento para ser baseado em porcentagem. Por fim, você pode restringir as visualizações às diretrizes.

Outra maneira é posicionar uma vista usando viés (porcentagem) e depois ancorar outras vistas nessa vista.

Dito isso, estamos pensando em como oferecer dimensões baseadas em porcentagem. Não posso fazer nenhuma promessa, mas é algo que gostaríamos de acrescentar.


1
0 down vote Poderia pedir um acompanhamento? Estou tentando definir um ImageView para ter 60% de largura, mas manter uma proporção de 16: 9. Quero que a largura seja fixa, mas a altura do ImageView seja dinâmica. Isso é possível com o ConstraintLayout? Estou lutando para fazê-lo funcionar - acabo com valores fixos de largura / altura de 0, a menos que eu especifique as dimensões codificadas.
precisa saber é o seguinte

3
@ MattWilliams89 Existe um parâmetro chamado layout_constraintDimensionRatio, acho que pode ser útil no seu caso, escreva "16: 9" lá. Não consegui tentando construir seu layout com ele, porém, a imagem fica enorme
Yury Fedorov

1
@RomainGuy, como você altera o posicionamento em porcentagem no cabeçalho das linhas de guia ?. Eu tentei clique direito e nada aparece
Edijae Crusar

21
Para aqueles que se perguntam exatamente qual é o cabeçalho da diretriz, é o círculo que tem uma seta para cima ou para baixo ou um símbolo de porcentagem. Clicar nesse botão alterna entre app: layout_constraintGuide_begin, app: layout_constraintGuide_end e app: layout_constraintGuide_percent em XML. Encontrei um pequeno problema (no ConstraintLayout versão 1.0.0-alpha8, em que tive que clicar na diretriz, manter pressionado o mouse e arrastar para o círculo para alterná-las no editor, mas tenho certeza de que esse erro será corrigido em breve #
21416 Lustig

4
Você também pode definir isso no XML do layout usandoapp:layout_constraintGuide_percentage
piratemurray

215

Pode ser útil ter uma referência rápida aqui.

Colocação de visualizações

Use uma diretriz com app:layout_constraintGuide_percentcomo esta:

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.5"/>

E então você pode usar esta diretriz como pontos de ancoragem para outras visualizações.

ou

Use o viés com app:layout_constraintHorizontal_biase / ou app:layout_constraintVertical_biaspara modificar o local da visualização quando o espaço disponível permitir

<Button
    ...
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintHorizontal_bias="0.25"
    ...
    />

Tamanho das visualizações

Outro valor baseado em porcentagem é a altura e / ou largura dos elementos, com app:layout_constraintHeight_percente / ou app:layout_constraintWidth_percent:

<Button
    ...
    android:layout_width="0dp"
    app:layout_constraintWidth_percent="0.5"
    ...
    />

3
por que tem largura definida como 1dp?
user924

1
@ user924 Teria sentido dar uma diretriz com uma largura de 0dp, não sei por que os desenvolvedores que implementaram isso decidiram por 1dp. Talvez porque 0dp seja considerado "esticado" ao usar pesos.
Amir Uval

3
@ user924: 0dpé usado no ConstraintLayout para indicar o dimensionamento dinâmico. Consulte developer.android.com/reference/android/support/constraint/…
serv-inc

1
@ serv-inc mas aqui 1dp, não 0dp.. é o que eu estou falando
user924

3
@ user924: você precisa configurá-lo para uma largura. 0dpjá está reservado, então 1dpparece sensato.
serv-inc

109

No "ConstraintLayout1.1.0-beta1", você pode usar o percentual para definir larguras e alturas.

android:layout_width="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent=".4"

Isso definirá a largura como 40% da largura da tela. Uma combinação disso e das diretrizes em porcentagem permite criar o layout baseado em porcentagem desejado.


6
No layout de restrição 1.0.2, o valor percentual para layout_constraintWidth_default não é suportado. Eu acho que o caminho certo é usar a Diretriz.
vovahost 29/07

1
está funcionando com o Android Studio 3.0 construído em 20 de outubro de 2017
douarbou 17/11

5
Conforme indicado na resposta, isso foi adicionado ao version 1.1ConstraintLayout. O adicional _default="percent"não é mais necessário na versão estável! Consulte "Dimensão percentual" em developer.android.com/reference/android/support/constraint/…
sunadorer

@hoford, para uma Visualização contendo texto, cujo tamanho deve ser definido em spunidades, como o tamanho do texto pode ser proporcional ao tamanho da visualização (que, por si só, é definido proporcionalmente ao tamanho total do layout, ou seja, em 'porcentagem') ?
Bliss

77

Com a nova versão do ConstraintLayout v1.1, agora você pode fazer o seguinte:

<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintWidth_percent="0.65" />

Isso restringirá o botão a 20% da altura e 65% da largura da visualização principal.


1
para mim só funcionou quando eu mudou de "android:" para "app:" -> app: layout_constraintHeight_percent = "0.2"
Kirill Karmazin

Isso é essencial para mim ao seguir o layout fluido do design do material. material.io/design/layout/…

@Adam, para uma Visualização contendo texto, cujo tamanho deve ser definido em spunidades, como o tamanho do texto pode ser proporcional ao tamanho da visualização (que, por si só, é definido proporcionalmente ao tamanho total do layout, ou seja, em 'porcentagem') ?
Bliss

1
@ Bliss Parece que isso poderia ajudar: developer.android.com/guide/topics/ui/look-and-feel/… Eu nunca o usei.
Adam

43

Como usar as Diretrizes

A resposta aceita é um pouco clara sobre como usar diretrizes e qual é o "cabeçalho".

Passos

Primeiro adicione uma Diretriz.

insira a descrição da imagem aqui

Selecione a guia ou mova-a um pouco para tornar as restrições visíveis.

insira a descrição da imagem aqui

Em seguida, clique no círculo redondo (o "cabeçalho") até que se torne um percentual. Em seguida, você pode arrastar essa porcentagem para 50% ou o que quiser.

insira a descrição da imagem aqui

Depois disso, você pode restringir sua exibição à Diretriz para torná-la uma porcentagem do pai (usando match_constraintna exibição).

insira a descrição da imagem aqui


Onde o 'cabeçalho' deve estar visível? Não aparece na minha opinião.
Marcel50506

@ Marcel50506, verifique se as visualizações Design e Blueprint estão sendo exibidas. Isso lhe dará a melhor chance de poder vê-lo. Se você pode ver a linha de orientação, tente clicar nela para selecioná-la. Se você não conseguir ver a linha, tente clicar no item da diretriz no menu Árvore de componentes que deve estar do lado esquerdo (supondo que você já tenha adicionado uma diretriz).
Suragch

1
Não vejo o círculo, mas ao clicar no lado esquerdo da diretriz posso alterá-lo para porcentagens. Problema de renderização, penso. Obrigado.
Marcel50506

Essa é a melhor resposta, pois propõe uma melhor abordagem de layout. Podemos alinhar várias opiniões sobre a base-guia em vez de adicionar percentual em apenas uma vista
Nguyen Minh Hien

33

A Diretriz é inestimável - e o aplicativo: layout_constraintGuide_percent é um ótimo amigo ... No entanto, às vezes, queremos porcentagens sem diretrizes. Agora é possível usar pesos :

android:layout_width="0dp"
app:layout_constraintHorizontal_weight="1"

Aqui está um exemplo mais completo que usa uma diretriz com pesos adicionais :

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context="android.itomerbu.layoutdemo.MainActivity">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.44"/>

    <Button
        android:id="@+id/btnThird"
        android:layout_width="0dp"
        app:layout_constraintHorizontal_weight="1"
        android:layout_height="wrap_content"
        android:text="@string/btnThird"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginBottom="8dp"
        app:layout_constraintRight_toLeftOf="@+id/btnTwoThirds"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"/>

    <Button
        android:id="@+id/btnTwoThirds"
        app:layout_constraintHorizontal_weight="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/btnTwoThirds"
        app:layout_constraintBottom_toBottomOf="@+id/btnThird"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/btnThird"/>
</android.support.constraint.ConstraintLayout>

2
@ Plumbus - Os pesos são equivalentes a porcentagens (qualquer porcentagem pode ser matematicamente convertida em peso e vice-versa). Por ser exigente quanto à terminologia, você perde o ponto da resposta.
Scott Biggs

11

Com o ConstraintLayout v1.1.2, a dimensão deve ser definida como 0dpe, em seguida, definir os atributos layout_constraintWidth_percentou layout_constraintHeight_percentpara um valor entre 0 e 1, como:

<!-- 50% width centered Button -->
<Button
    android:id="@+id/button"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintWidth_percent=".5" />

(Você não precisa definir app:layout_constraintWidth_default="percent"ou app:layout_constraintHeight_default="percent"com o ConstraintLayout 1.1.2 e seguintes versões)


10

O Constraint Layout 1.0, que cria uma visualização, ocupa uma porcentagem da tela necessária para a criação de duas diretrizes. No Layout de restrições 1.1, ficou mais simples, permitindo restringir facilmente qualquer visualização a uma porcentagem de largura ou altura.

insira a descrição da imagem aqui

Isso não é fantástico? Todas as visualizações suportam os atributos layout_constraintWidth_percent e layout_constraintHeight_percent. Isso fará com que a restrição seja corrigida em uma porcentagem do espaço disponível. Portanto, a expansão de um botão ou de um TextView para preencher uma porcentagem da tela pode ser feita com algumas linhas de XML.

Por exemplo, se você deseja definir a largura do botão para 70% da tela, é possível fazer o seguinte:

<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_constraintWidth_percent="0.7" />

Observe que você precisará colocar a dimensão como porcentagem para 0dp, conforme especificamos android: layout_width a 0dp acima.

Da mesma forma, se você deseja definir a altura do botão para 20% da tela, é possível fazer o seguinte:

<Button
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_constraintHeight_percent="0.2" />

Vejo! especificamos android: layout_height para 0dp dessa vez, pois queremos que o botão use a altura como porcentagem.


8

Experimente este código. Você pode alterar as porcentagens de altura e largura com app: layout_constraintHeight_percent e app: layout_constraintWidth_percent.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#FF00FF"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_percent=".6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent=".4"></LinearLayout>

</android.support.constraint.ConstraintLayout>

Gradle:

dependencies {
...
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}

insira a descrição da imagem aqui


7

você pode usá- app:layout_constraintVertical_weightlo da mesma forma que layout_weightemlinearlayout

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
    android:id="@+id/button4"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/button5"
    app:layout_constraintVertical_weight="1"/>

<Button
    android:id="@+id/button5"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button"
    app:layout_constraintLeft_toRightOf="@+id/button4"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintVertical_weight="1"/>
</android.support.constraint.ConstraintLayout>

NOTA: app:layout_constraintVertical_weight( app:layout_constraintHorizontal_weight) funcionará com android:layout_width="0dp"(android:layout_height="0dp"


5

Para alguém que possa ser útil, você pode usar layout_constraintDimensionRatioqualquer visualização filho dentro de ConstraintLayoute podemos definir a proporção Altura ou Largura da outra dimensão (pelo menos um deve ser 0dp de largura ou altura) exemplo

 <ImageView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:src="@drawable/top_image"
        app:layout_constraintDimensionRatio="16:9"        
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

neste caso, a proporção é 16: 9, app:layout_constraintDimensionRatio="16:9" você pode encontrar mais informações AQUI


3

Eu sei que isso não é diretamente o que o OP estava pedindo originalmente, mas isso me ajudou muito nessa situação quando eu tive uma pergunta semelhante. . Adicione isso ao seu onCreate na atividade de pergunta. (Altera para 80%)

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);

int width = dm.widthPixels;
int height = dm.heightPixels;

getWindow().setLayout((int)(width * 0.8), (int)(height * 0.8));

2

Simplesmente, basta substituir, na sua etiqueta de diretrizes

app:layout_constraintGuide_begin="291dp"

com

app:layout_constraintGuide_percent="0.7"

onde 0,7 significa 70%.

Além disso, se você tentar arrastar as diretrizes agora, o valor arrastado será exibido em% de idade.


2

Usando Diretrizes, você pode alterar o posicionamento para ser baseado em porcentagem

<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/>

Você também pode usar este caminho

android:layout_width="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.4"
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.