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?

Yury Fedorov
fonte
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.

Romain Guy
fonte
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"
    ...
    />
Amir Uval
fonte
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.

hoford
fonte
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.

Adão
fonte
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

Suragch
fonte
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>
TomerBu
fonte
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)

Bubu
fonte
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.

Ashish Satpute
fonte
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

amor ao vivo
fonte
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"

vuhung3990
fonte
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

Javier
fonte
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));
David Azzi
fonte
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.

Udit Kapahi
fonte
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"
Ashish Satpute
fonte