¿Cómo hacer que ConstraintLayout funcione con valores porcentuales?

207

Con una vista previa 1 de Android Studio 2.2 Google lanzó un nuevo diseño en su biblioteca de soporte: ConstraintLayout. Con ConstraintLayout es más fácil usar una herramienta de diseño en Android Studio, pero no encontré una forma de usar tamaños relativos (porcentajes o 'pesos' como en LinearLayout). ¿Hay alguna manera de definir las restricciones basadas en porcentajes? Por ejemplo, ¿hacer que una vista tome el 40% de una pantalla, crear un margen del 20% entre las vistas, establecer el ancho de una vista al 50% del ancho de otra vista?

Yury Fedorov
fuente
3
El porcentaje de soporte para ancho o alto se agregó en version 1.1ConstraintLayout. Consulte "Dimensión porcentual" en developer.android.com/reference/android/support/constraint/… o algunas de las respuestas más recientes.
Sunadorer

Respuestas:

225

Actualmente puede hacer esto de varias maneras.

Una es crear pautas (haga clic con el botón derecho en el área de diseño, luego haga clic en agregar pauta vertical / horizontal). Luego puede hacer clic en el "encabezado" de la guía para cambiar el posicionamiento para que esté basado en porcentajes. Finalmente, puede restringir las vistas a pautas.

Otra forma es posicionar una vista usando sesgo (porcentaje) y luego anclar otras vistas a esa vista.

Dicho esto, hemos estado pensando en cómo ofrecer dimensiones basadas en porcentajes. No puedo hacer ninguna promesa, pero es algo que nos gustaría agregar.

Romain Guy
fuente
1
0 voto negativo ¿Puedo pedir un seguimiento? Estoy tratando de configurar un ImageView para tener un ancho del 60%, pero mantener una relación de aspecto de 16: 9. Quiero que el ancho sea fijo, pero la altura de ImageView sea dinámica. ¿Es eso posible con ConstraintLayout? Estoy luchando para que funcione: termino con valores fijos de ancho / alto de 0 a menos que especifique dimensiones codificadas.
MattWilliams89
3
@ MattWilliams89 Hay un parámetro llamado layout_constraintDimensionRatio, supongo que puede ser útil en su caso, escriba "16: 9" allí. Sin embargo, no logré construir su diseño con él, la imagen se vuelve enorme
Yury Fedorov
1
@RomainGuy ¿cómo se cambia el posicionamiento para que esté en porcentaje en el encabezado de guidlines? He intentado hacer clic derecho y no aparece nada
Edijae Crusar
21
Para aquellos que se preguntan exactamente cuál es el encabezado de la guía, es el círculo que tiene una flecha hacia arriba o hacia abajo o un símbolo de porcentaje. Al hacer clic en eso, se alterna entre la aplicación: layout_constraintGuide_begin, la aplicación: layout_constraintGuide_end y la aplicación: layout_constraintGuide_percent en XML. Encontré un pequeño problema (en ConstraintLayout versión 1.0.0-alpha8 donde tuve que hacer clic en la guía, mantener presionado el mouse y arrastrar al círculo para alternarlos en el editor, pero estoy seguro de que este error se solucionará pronto .
lustig
44
También puede configurar esto en el XML del diseño usandoapp:layout_constraintGuide_percentage
piratemurray
215

Puede ser útil tener una referencia rápida aquí.

Colocación de vistas

Usar una guía de app:layout_constraintGuide_percentla siguiente manera:

<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"/>

Y luego puede usar esta guía como puntos de anclaje para otras vistas.

o

Usar sesgo con app:layout_constraintHorizontal_biasy / oapp:layout_constraintVertical_bias para modificar la ubicación de la vista cuando el espacio disponible lo permita

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

Tamaño de vistas

Otro valor basado en porcentaje es la altura y / o el ancho de los elementos, con app:layout_constraintHeight_percenty / o app:layout_constraintWidth_percent:

<Button
    ...
    android:layout_width="0dp"
    app:layout_constraintWidth_percent="0.5"
    ...
    />
Amir Uval
fuente
3
¿Por qué tiene el ancho establecido en 1dp?
user924
1
@ user924 Hubiera tenido sentido dar una directriz con un ancho de 0dp, no sé por qué los desarrolladores que implementaron esto decidieron 1dp. Tal vez porque 0dp se considera "estirar" cuando se usan pesas.
Amir Uval
3
@ user924: 0dpse usa en ConstraintLayout para indicar el tamaño dinámico. Ver developer.android.com/reference/android/support/constraint/…
serv-inc
1
@ serv-inc pero aquí 1dp, no 0dp... es de lo que estoy hablando
user924
3
@ user924: debe establecerlo en un ancho. 0dpya está reservado, por lo que 1dpparece sensato.
serv-inc
109

A partir de "ConstraintLayout1.1.0-beta1" puede usar el porcentaje para definir anchos y alturas.

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

Esto definirá el ancho como el 40% del ancho de la pantalla. Una combinación de esto y pautas en porcentaje le permite crear cualquier diseño basado en porcentaje que desee.

hoford
fuente
66
En el diseño de restricción 1.0.2, el valor porcentual de layout_constraintWidth_default no es compatible. Creo que la forma correcta es usar la Guía.
vovahost
1
funciona con Android Studio 3.0 creado el 20 de octubre de 2017
douarbou el
55
Como se indica en la respuesta, esto se agregó en version 1.1ConstraintLayout. ¡El adicional _default="percent"ya no es necesario en la versión estable! Consulte "Dimensión porcentual" en developer.android.com/reference/android/support/constraint/…
sunadorer
@hoford, para una Vista que contiene texto, cuyo tamaño se definirá en spunidades, ¿cómo podría el tamaño del texto ser auto proporcional al tamaño de la vista (que, por sí mismo, se define proporcionalmente al tamaño total del diseño, es decir, en 'porcentaje') ?
Dicha
77

Con la nueva versión de ConstraintLayout v1.1 ahora puede hacer lo siguiente:

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

Esto limitará el botón para que tenga un 20% de la altura y un 65% del ancho de la vista principal.

Adán
fuente
1
para mí funcionó solo cuando cambié de "android:" a "app:" -> app: layout_constraintHeight_percent = "0.2"
Kirill Karmazin
Esto es imprescindible para mí cuando sigo el diseño fluido del diseño del material. material.io/design/layout/…
@ Adam, para una Vista que contiene texto, cuyo tamaño se definirá en spunidades, ¿cómo podría el tamaño del texto ser auto proporcional al tamaño de la vista (que, por sí mismo, se define proporcionalmente al tamaño total del diseño, es decir, en 'porcentaje') ?
Dicha
1
@Bliss Suena como esto podría ayudar: developer.android.com/guide/topics/ui/look-and-feel/… Sin embargo, nunca lo he usado.
Adam
43

Cómo usar las pautas

La respuesta aceptada es poco clara sobre cómo usar las pautas y cuál es el "encabezado".

Pasos

Primero agregue una directriz.

ingrese la descripción de la imagen aquí

Seleccione la línea de guía o muévala un poco para hacer visibles las restricciones.

ingrese la descripción de la imagen aquí

Luego haga clic en el círculo redondo (el "encabezado") hasta que se convierta en un porcentaje. Luego puede arrastrar este porcentaje al 50% o lo que quiera.

ingrese la descripción de la imagen aquí

Después de eso, puede restringir su vista a la Guía para que sea un porcentaje del padre (usando match_constrainten la vista).

ingrese la descripción de la imagen aquí

Suragch
fuente
¿Dónde debería estar visible el 'encabezado'? No se muestra en mi opinión.
Marcel50506
@ Marcel50506, asegúrese de que se muestren las vistas Diseño y Plano. Eso te dará la mejor oportunidad de poder verlo. Si puede ver la línea de guía, intente hacer clic en ella para seleccionarla. Si no puede ver la línea, intente hacer clic en el elemento de la guía en el menú del Árbol de componentes que debería estar en el lado izquierdo (suponiendo que ya haya agregado una guía).
Suragch
1
No veo el círculo, pero al hacer clic a la izquierda de la guía, puedo modificarlo en porcentajes. Creo que es un problema de representación. Gracias.
Marcel50506
Esta es la mejor respuesta porque propone un mejor enfoque de diseño. Podemos alinear múltiples vistas en la guía base en lugar de agregar un porcentaje en una sola vista
Nguyen Minh Hien
33

La Guía es invaluable, y la aplicación: layout_constraintGuide_percent es un gran amigo ... Sin embargo, a veces queremos porcentajes sin pautas. Ahora es posible usar pesas :

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

Aquí hay un ejemplo más completo que usa una guía con pesos adicionales :

<?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
fuente
2
@Plumbus: los pesos son equivalentes a porcentajes (cualquier porcentaje se puede convertir matemáticamente en un peso y viceversa). Al ser quisquilloso con la terminología, pierde el punto de la respuesta.
Scott Biggs
11

Con ConstraintLayout v1.1.2, la dimensión debe establecerse en 0dpy luego establecer los atributos layout_constraintWidth_percento layout_constraintHeight_percenten un valor entre 0 y 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" />

(No es necesario configurar app:layout_constraintWidth_default="percent"o app:layout_constraintHeight_default="percent"con ConstraintLayout 1.1.2 y las siguientes versiones)

Bubu
fuente
10

Restricción Layout 1.0 haciendo que una vista ocupe un porcentaje de la pantalla requerida haciendo dos pautas. En Restraint Layout 1.1 se ha simplificado permitiéndole restringir fácilmente cualquier vista a un porcentaje de ancho o alto.

ingrese la descripción de la imagen aquí

¿No es esto fantástico? Todas las vistas admiten los atributos layout_constraintWidth_percent y layout_constraintHeight_percent. Esto hará que la restricción se fije en un porcentaje del espacio disponible. Por lo tanto, hacer que un botón o una vista de texto se expanda para llenar un porcentaje de la pantalla se puede hacer con unas pocas líneas de XML.

Por ejemplo, si desea establecer el ancho del botón al 70% de la pantalla, puede hacerlo así:

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

Tenga en cuenta que deberá colocar la dimensión como porcentaje a 0dp, ya que hemos especificado android: layout_width a 0dp arriba.

Del mismo modo, si desea establecer la altura del botón al 20% de la pantalla, puede hacerlo así:

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

¡Ver! esta vez hemos especificado android: layout_height a 0dp ya que queremos que el botón use la altura como porcentaje.

Satputa Ashish
fuente
8

Prueba este código. Puede cambiar los porcentajes de altura y anchura con app: layout_constraintHeight_percent y 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'
}

ingrese la descripción de la imagen aquí

vive el amor
fuente
7

puedes usarlo app:layout_constraintVertical_weightigual que layout_weightenlinearlayout

<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á con android:layout_width="0dp"(android:layout_height="0dp"

vuhung3990
fuente
5

Para alguien que pueda resultarle útil, puede usar layout_constraintDimensionRatioim cualquier vista secundaria dentro de ConstraintLayoutay podemos definir el alto o el ancho de una relación de la otra dimensión (al menos uno debe ser 0dp, ya sea ancho o alto)

 <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"/>

en este caso la relación de aspecto es 16: 9 app:layout_constraintDimensionRatio="16:9" puedes encontrar más información AQUÍ

Javier
fuente
3

Sé que esto no es directamente lo que OP estaba pidiendo originalmente, pero esto me ayudó mucho en esta situación cuando tuve una pregunta similar. Agregar esto para las personas que buscan cambiar el tamaño de la ventana de diseño (que uso regularmente), a través del código . Agregue esto a su onCreate en la actividad de la pregunta. (Lo cambia al 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
fuente
2

Simplemente, simplemente reemplace, en su etiqueta de guía

app:layout_constraintGuide_begin="291dp"

con

app:layout_constraintGuide_percent="0.7"

donde 0.7 significa 70%.

Además, si ahora intenta arrastrar pautas, el valor arrastrado ahora aparecerá en% de edad.

Udit Kapahi
fuente
2

Con las pautas, puede cambiar la posición para que se base en porcentajes

<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"/>

También puedes usar de esta manera

android:layout_width="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.4"
Satputa Ashish
fuente