Come far funzionare ConstraintLayout con valori percentuali?


207

Con un Preview 1 di Android Studio 2.2 Google ha rilasciato un nuovo layout nella sua libreria di supporto: ConstraintLayout. Con ConstraintLayout è più facile utilizzare uno strumento di progettazione in Android Studio, ma non ho trovato il modo di utilizzare dimensioni relative (percentuali o "pesi" come in LinearLayout). C'è un modo per definire i vincoli in base alle percentuali? Ad esempio, fare in modo che una vista occupi il 40% di uno schermo, creare un margine del 20% tra le viste, impostare la larghezza di una vista al 50% della larghezza di un'altra vista?


3
Il supporto percentuale per larghezza o altezza è stato aggiunto in version 1.1ConstraintLayout. Vedi "Dimensione percentuale" su developer.android.com/reference/android/support/constraint/… o alcune delle risposte più recenti.
— Sunadorer,

Risposte:


225

Al momento puoi farlo in un paio di modi.

Uno è quello di creare linee guida (fare clic con il pulsante destro del mouse sull'area di progettazione, quindi fare clic su Aggiungi linea guida verticale / orizzontale). È quindi possibile fare clic sull'intestazione della linea guida per modificare il posizionamento in base percentuale. Infine, puoi limitare le viste alle linee guida.

Un altro modo è posizionare una vista usando la deviazione (percentuale) e quindi ancorare altre viste a quella vista.

Detto questo, abbiamo pensato a come offrire dimensioni basate sulla percentuale. Non posso fare nessuna promessa ma è qualcosa che vorremmo aggiungere.


1
0 voto negativo Potrei chiedere un seguito? Sto cercando di impostare un ImageView con una larghezza del 60% ma mantenere un rapporto di formato 16: 9. Voglio che la larghezza sia fissa, ma l'altezza di ImageView sia dinamica. È possibile con ConstraintLayout? Sto lottando per farlo funzionare - finisco con valori di larghezza / altezza fissi di 0 a meno che non specifichi dimensioni codificate.
— MattWilliams89,

3
@ MattWilliams89 Esiste un parametro chiamato layout_constraintDimensionRatio, immagino possa essere utile nel tuo caso, scrivi "16: 9" lì. Non sono riuscito a provare a costruire il tuo layout con esso, tuttavia l'immagine diventa enorme
— Yury Fedorov

1
@RomainGuy come si modifica il posizionamento in percentuale sull'intestazione delle linee guida ?. ho provato a fare clic con il pulsante destro del mouse e non viene visualizzato nulla
— Edijae Crusar,

21
Per quelli che si chiedono esattamente quale sia l'intestazione della linea guida, è il cerchio che ha una freccia su o giù o un simbolo di percentuale. Facendo clic su ciò passa tra app: layout_constraintGuide_begin, app: layout_constraintGuide_end e app: layout_constraintGuide_percent in XML. Ho riscontrato un piccolo problema (su ConstraintLayout versione 1.0.0-alpha8 in cui ho dovuto fare clic sulla linea guida, tenere premuto il mouse e trascinare sul cerchio per attivarli nell'editor, ma sono sicuro che questo bug verrà risolto presto .
— Lustig

4
Puoi anche impostarlo nell'XML del layout usandoapp:layout_constraintGuide_percentage
— piratemurray l'

215

Potrebbe essere utile avere un riferimento rapido qui.

Collocazione di viste

Usa una linea guida con app:layout_constraintGuide_percentquesto:

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

Quindi puoi utilizzare questa linea guida come punti di ancoraggio per altre viste.

o

Utilizzare la deviazione con app:layout_constraintHorizontal_biase / o app:layout_constraintVertical_biasper modificare la posizione della vista quando lo spazio disponibile lo consente

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

Dimensioni delle viste

Un altro valore basato su percentuale è altezza e / o larghezza degli elementi, con app:layout_constraintHeight_percente / o app:layout_constraintWidth_percent:

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

3
perché ha la larghezza impostata su 1dp?
— user924

1
@ user924 Avrebbe avuto senso dare una linea guida con una larghezza di 0dp, non so perché gli sviluppatori che lo hanno implementato abbiano deciso di 1dp. Forse perché 0dp è considerato "allungato" quando si usano i pesi.
— Amir Uval

3
@ user924: 0dpviene utilizzato in ConstraintLayout per indicare il dimensionamento dinamico. Vedi developer.android.com/reference/android/support/constraint/…
— serv-inc

1
@ serv-inc ma qui 1dp, non 0dp.. è quello di cui sto parlando
— user924

3
@ user924: è necessario impostarlo su una larghezza. 0dpè già riservato, quindi 1dpsembra ragionevole.
— serv-inc

109

A partire da "ConstraintLayout1.1.0-beta1" puoi usare percent per definire larghezze e altezze.

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

Ciò definirà la larghezza pari al 40% della larghezza dello schermo. Una combinazione di questo e linee guida in percentuale consente di creare qualsiasi layout basato su percentuale desiderato.


6
Nel layout dei vincoli 1.0.2 il valore percentuale per layout_constraintWidth_default non è supportato. Penso che il modo giusto sia usare le Linee guida.
— vovahost,

1
funziona con Android Studio 3.0 creato il 20 ottobre 2017
— douarbou,

5
Come indicato nella risposta, questo è stato aggiunto in version 1.1ConstraintLayout. L'addizionale _default="percent"non è più necessario sulla versione stabile! Vedi "Dimensione percentuale" su developer.android.com/reference/android/support/constraint/…
— sunadorer

@hoford, per una vista contenente testo, la cui dimensione deve essere definita in spunità, come potrebbe la dimensione del testo essere auto-proporzionale alla dimensione della vista (che è, di per sé, definita proporzionalmente alla dimensione totale del layout, cioè in 'percentuale') ?
— Beatitudine il

77

Con la nuova versione di ConstraintLayout v1.1 è ora possibile effettuare le seguenti operazioni:

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

Ciò vincolerà il pulsante al 20% dell'altezza e al 65% della larghezza della vista padre.


1
per me ha funzionato solo quando sono passato da "android:" a "app:" -> app: layout_constraintHeight_percent = "0.2"
— Kirill Karmazin

Questo è un must per me quando seguo la disposizione fluida del design del materiale. material.io/design/layout/…

@Adam, per una vista contenente testo, la cui dimensione deve essere definita in spunità, come potrebbe la dimensione del testo essere auto-proporzionale alla dimensione della vista (che è, di per sé, definita proporzionalmente alla dimensione totale del layout, cioè in 'percentuale') ?
— Beatitudine il

1
@Bliss Suona come questo potrebbe aiutare: developer.android.com/guide/topics/ui/look-and-feel/… Non l'ho mai usato da solo.
— Adam,

43

Come utilizzare le linee guida

La risposta accettata non è chiara su come utilizzare le linee guida e qual è il "titolo".

passi

Per prima cosa aggiungi una linea guida.

inserisci qui la descrizione dell'immagine

Seleziona la Linea guida o spostala leggermente per rendere visibili i vincoli.

inserisci qui la descrizione dell'immagine

Quindi fai clic sul cerchio rotondo ("intestazione") fino a quando non diventa una percentuale. È quindi possibile trascinare questa percentuale fino al 50% o qualsiasi altra cosa si desideri.

inserisci qui la descrizione dell'immagine

Dopodiché puoi vincolare la tua vista alla Linea guida per renderla una percentuale del genitore (usando match_constraintsulla vista).

inserisci qui la descrizione dell'immagine


Dove dovrebbe essere visibile l'intestazione? A mio avviso non si presenta.
— Marcel50506,

@ Marcel50506, assicurati che siano visualizzate sia le viste Design che Blueprint. Questo ti darà le migliori possibilità di poterlo vedere. Se riesci a vedere la linea guida, prova a fare clic su di essa per selezionarla. Se non riesci a vedere la linea, prova a fare clic sulla voce della linea guida nel menu Albero dei componenti che dovrebbe essere sul lato sinistro (supponendo che tu abbia già aggiunto una linea guida).
— Suragch,

1
Non vedo il cerchio, ma quando si fa clic a sinistra della linea guida posso modificarlo in percentuale. Penso che il problema di rendering. Grazie.
— Marcel50506,

Questa è la risposta migliore perché propone un approccio di layout migliore. Possiamo allineare più viste sulla linea guida di base invece di aggiungere una percentuale su una sola vista
— Nguyen Minh Hien,

33

La linea guida è preziosa e l'app: layout_constraintGuide_percent è un grande amico ... Tuttavia a volte vogliamo percentuali senza linee guida. Ora è possibile utilizzare i pesi :

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

Ecco un esempio più completo che utilizza una linea guida con pesi aggiuntivi :

<?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 - I pesi sono equivalenti alle percentuali (qualsiasi percentuale può essere convertita matematicamente in un peso e viceversa). Essendo pignoli sulla terminologia, perdi il punto della risposta.
— Scott Biggs,

11

Con ConstraintLayout v1.1.2, la dimensione deve essere impostata su 0dpe quindi impostare gli attributi layout_constraintWidth_percento layout_constraintHeight_percentsu un valore compreso tra 0 e 1 come:

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

(Non è necessario impostare app:layout_constraintWidth_default="percent"o app:layout_constraintHeight_default="percent"con ConstraintLayout 1.1.2 e versioni successive)


10

Constraint Layout 1.0 facendo in modo che una vista occupi una percentuale dello schermo richiesta facendo due linee guida. In Constraint Layout 1.1 è stato semplificato consentendo di limitare facilmente qualsiasi vista a una larghezza o altezza percentuale.

inserisci qui la descrizione dell'immagine

Non è fantastico? Tutte le viste supportano gli attributi layout_constraintWidth_percent e layout_constraintHeight_percent. Ciò farà sì che il vincolo venga fissato in una percentuale dello spazio disponibile. Quindi fare un pulsante o un TextView espandersi per riempire una percentuale dello schermo può essere fatto con poche righe di XML.

Ad esempio, se si desidera impostare la larghezza del pulsante sul 70% dello schermo, è possibile farlo in questo modo:

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

Tieni presente che dovrai inserire la dimensione da utilizzare come percentuale a 0 dpi come abbiamo specificato android: layout_width a 0 dpi sopra.

Allo stesso modo, se si desidera impostare l'altezza del pulsante sul 20% dello schermo, è possibile farlo in questo modo:

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

Vedere! abbiamo specificato android: layout_height a 0dp questa volta poiché vogliamo che il pulsante utilizzi l'altezza come percentuale.


8

Prova questo codice. Puoi modificare le percentuali di altezza e larghezza con l'app: layout_constraintHeight_percent e l'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'
}

inserisci qui la descrizione dell'immagine


7

puoi usarlo app:layout_constraintVertical_weightcome layout_weightinlinearlayout

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


5

Per qualcuno che potrebbe essere utile, puoi usare layout_constraintDimensionRatioim qualsiasi vista figlio all'interno di a ConstraintLayoute possiamo definire l'altezza o la larghezza un rapporto dell'altra dimensione (almeno uno deve essere 0dp o larghezza o altezza) esempio

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

in questo caso le proporzioni sono 16: 9 app:layout_constraintDimensionRatio="16:9" puoi trovare maggiori informazioni QUI


3

So che questo non è direttamente quello che l'OP stava chiedendo originariamente, ma questo mi ha aiutato molto in questa situazione quando avevo una domanda simile. . Aggiungi questo al tuo onCreate nell'attività della domanda. (Cambia in 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

Semplicemente, basta sostituire, nel tag della linea guida

app:layout_constraintGuide_begin="291dp"

con

app:layout_constraintGuide_percent="0.7"

dove 0.7 significa 70%.

Inoltre, se ora provi a trascinare le linee guida, il valore trascinato verrà ora visualizzato in% età.


2

Utilizzando le Linee guida è possibile modificare il posizionamento in base alla percentuale

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

Puoi anche usare in questo modo

android:layout_width="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.4"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.