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.