Spaziatura uniforme delle viste usando ConstraintLayout


Risposte:


323

Esistono due modi per ottenere ciò utilizzando ConstraintLayout: Catene e Linee guida . Per utilizzare le catene, assicurati di utilizzare ConstraintLayoutBeta 3 o versioni successive e se desideri utilizzare l'editor del layout visivo in Android Studio, assicurati di utilizzare Android Studio 2.3 Beta 1 o versioni successive.

Metodo 1 - Utilizzo delle catene

Apri l'editor di layout e aggiungi i tuoi widget normalmente, aggiungendo i vincoli principali secondo necessità. In questo caso, ho aggiunto due pulsanti con vincoli nella parte inferiore del genitore e lato del genitore (lato sinistro per il pulsante Salva e lato destro per il pulsante Condividi):

inserisci qui la descrizione dell'immagine

Si noti che in questo stato, se si passa alla vista orizzontale, le viste non riempiono il genitore ma sono ancorate agli angoli:

inserisci qui la descrizione dell'immagine

Evidenzia entrambe le viste, facendo clic Ctrl / Cmd o trascinando una casella attorno alle viste:

inserisci qui la descrizione dell'immagine

Quindi fare clic con il tasto destro del mouse sulle viste e selezionare "Centra orizzontalmente":

inserisci qui la descrizione dell'immagine

Ciò imposta una connessione bidirezionale tra le viste (che è come viene definita una catena). Per impostazione predefinita, lo stile della catena è "spread", che viene applicato anche quando non è incluso alcun attributo XML. Attenersi a questo stile di catena ma impostando la larghezza delle nostre viste per 0dpconsentire alle viste di riempire lo spazio disponibile, diffondendo uniformemente tra i genitori:

inserisci qui la descrizione dell'immagine

Ciò è più evidente nella vista orizzontale:

inserisci qui la descrizione dell'immagine

Se si preferisce saltare l'editor di layout, l'XML risultante sarà simile a:

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

<Button
    android:id="@+id/button_save"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="@string/button_save_text"
    android:layout_marginStart="8dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="4dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/button_share"
    app:layout_constraintHorizontal_chainStyle="spread" />

<Button
    android:id="@+id/button_share"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="@string/button_share_text"
    android:layout_marginStart="4dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp"
    app:layout_constraintLeft_toRightOf="@+id/button_save"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintBottom_toBottomOf="parent" />

</android.support.constraint.ConstraintLayout>

Dettagli:

  • impostare la larghezza di ciascun elemento su 0dpo MATCH_CONSTRAINTconsentire alle viste di riempire il genitore (facoltativo)
  • le viste devono essere collegate in modo bidirezionale (a destra dei collegamenti dei pulsanti di salvataggio per condividere il pulsante, a sinistra dei collegamenti dei pulsanti di condivisione per salvare il pulsante), ciò avverrà automaticamente tramite l'editor di layout quando si sceglie "Centra orizzontalmente"
  • la prima vista nella catena può specificare lo stile della catena tramite layout_constraintHorizontal_chainStyle, consultare la documentazione per vari stili di catena, se lo stile di catena viene omesso, il valore predefinito è "spread"
  • la ponderazione della catena può essere regolata tramite layout_constraintHorizontal_weight
  • questo esempio è per una catena orizzontale, ci sono attributi corrispondenti per catene verticali

Metodo 2 - Utilizzo di una linea guida

Apri il layout nell'editor e fai clic sul pulsante Linee guida:

inserisci qui la descrizione dell'immagine

Quindi selezionare "Aggiungi linea guida verticale": inserisci qui la descrizione dell'immagine

Apparirà una nuova linea guida, che per impostazione predefinita sarà probabilmente ancorata a sinistra in valori relativi (indicata dalla freccia rivolta a sinistra):

linee guida relative all'editor di layout

Fai clic sulla freccia rivolta a sinistra per passare a un valore percentuale, quindi trascina la linea guida sul segno del 50%:

linea guida percentuale dell'editor di layout

La linea guida può ora essere utilizzata come ancoraggio per altre viste. Nel mio esempio, ho collegato la linea guida del pulsante Salva e la parte sinistra del pulsante Condividi alla linea guida:

layout finale

Se si desidera che le viste riempiano lo spazio disponibile, il vincolo deve essere impostato su "Qualsiasi dimensione" (le linee ondulate che corrono orizzontalmente):

qualsiasi vincolo di dimensione

(È uguale all'impostazione di layout_widtha 0dp).

Una linea guida può anche essere creata in XML abbastanza facilmente piuttosto che usare l'editor di layout:

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

1
Non sono riuscito a trovare un modo per creare una linea guida con un vincolo. Voglio che una linea guida orizzontale sia nel mezzo di due viste. Immagina una vista più grande con un'altezza di 100 dp in alto e una più piccola con un'altezza di 50 dp in basso. Voglio mettere una linea guida nel mezzo dello spazio tra di loro.
headsvk,

3
Non penso che tu possa aggiungere vincoli alle linee guida stesse. È possibile aggiungere più linee guida e quindi limitare le viste a tali linee guida. Potresti voler pubblicare una nuova domanda con i dettagli su ciò che stai cercando di ottenere. Sentiti libero di incollarlo anche qui.
AdamK,

Grazie, caro signore. È stato un aiuto tempestivo ed efficace.
iSofia,

Voglio dare una larghezza proporzionale alle viste. Ad esempio, voglio che il pulsante di condivisione abbia il doppio della larghezza del pulsante di salvataggio. Senza usare le linee guida poiché le mie opinioni non sono posizionate una accanto all'altra come in questo esempio. È possibile?
Shubham Naik,

Devi convertire i valori indicati dalle linee guida in margini o imbottiture effettivi. Le linee guida funzionano solo in modalità progettazione.
Abhinav Saxena,

49

Per creare 2 viste nella stessa linea, uguale larghezza, è sufficiente definire

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <Button
        android:id="@+id/button1"
        android:layout_width="0dp"  
        android:layout_height="wrap_content"
        android:text="Button 1"
        app:layout_constraintEnd_toStartOf="@+id/button2"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/button1" />

</android.support.constraint.ConstraintLayout>

Nota

  • larghezza = 0dp ( MATCH_CONSTRAINT)
  • Vincolo di button1e button2deve piacere sopra

Risultato

ALTRO
Se vuoi View1più di quanto View2puoi usare weighto percent.
Esempio, View1larghezza = 2 * View2larghezza uso peso

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <Button
        android:id="@+id/button3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 3"
        app:layout_constraintEnd_toStartOf="@+id/button4"
        app:layout_constraintHorizontal_weight="2"
        app:layout_constraintStart_toStartOf="parent"
        />

    <Button
        android:id="@+id/button4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@+id/button3"
        />

</android.support.constraint.ConstraintLayout>

Risultato

Esempio, View1larghezza = 2 * View2larghezza usa percentuale

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <Button
        android:id="@+id/button5"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 5"
        app:layout_constraintEnd_toStartOf="@+id/button6"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintWidth_percent="0.667"
        />

    <Button
        android:id="@+id/button6"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 6"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/button5"
        app:layout_constraintWidth_percent="0.333"
        />

</android.support.constraint.ConstraintLayout>

Risultato


23

Bene, se aiuta qualcuno

la chiave è qui app:layout_constraintHorizontal_weight="1"e
la cosa migliore del layout dei vincoli è che supporta la dipendenza circolare e qui è quello che ho fatto usando esattamente questo.

Per il primo figlio
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"

Per il secondo figlio

app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"

ecco la demo completa

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInputParent"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent">

    <EditText
        android:id="@+id/editTextParent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/state" />
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInputFirstChild"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"
    app:layout_constraintHorizontal_weight="1"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textInputParent">

    <EditText
        android:id="@+id/editTextChildOne"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/pin_code" />
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInputSecondChild"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintHorizontal_weight="1"
    app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textInputParent">

    <EditText
        android:id="@+id/editTextChildSecond"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/country" />
</android.support.design.widget.TextInputLayout>

9

Devi leggere delle catene ponderate. Un esempio di codice è qui.

<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="wrap_content"
    >

    <TextView
        android:id="@+id/figure_1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintEnd_toStartOf="@id/figure_2"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toStartOf="parent"
        tools:text="1"
        />

    <TextView
        android:id="@+id/figure_2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintEnd_toStartOf="@id/figure_3"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@id/figure_1"
        tools:text="2"
        />

    <TextView
        android:id="@+id/figure_3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintEnd_toStartOf="@id/figure_4"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@id/figure_2"
        tools:text="3"
        />

    <TextView
        android:id="@+id/figure_4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@id/figure_3"
        tools:text="4"
        />
</android.support.constraint.ConstraintLayout>

Così, insieme android:layout_width="0dp", app:layout_constraintHorizontal_weight="1"e collegare ogni vista con i vicini come:

app:layout_constraintStart_toEndOf="@id/figure_2"
app:layout_constraintEnd_toStartOf="@id/figure_4"

inserisci qui la descrizione dell'immagine


che senso ha postare un'altra risposta esattamente come un'altra, pubblicata due anni fa?

@Subzero, ho visto molte volte risposte uguali ad alto tasso. Anche le righe di codice erano uguali. Ho il sospetto, alcuni autori hanno copiato dal mio e hanno anche ottenuto più vantaggi. In questo caso le risposte sono diverse, ho anche usato altre fonti per capire come funzionano i pesi ConstraintLayoute solo la prima risposta non è stata sufficiente per ottenere un'immagine sopra.
CoolMind

3

Una volta che hai i tuoi oggetti incatenati, puoi comunque usare i pesi su di essi come il layout relativo per mantenerli uniformemente distanziati. L'esempio seguente mostra come mantenerli uniformemente distanziati con visualizzazioni di testo di dimensioni diverse.

<TextView1
     app:layout_constraintHorizontal_weight="1" />
 <TextView2
     app:layout_constraintHorizontal_weight="1" />
 <TextView3
     app:layout_constraintHorizontal_weight="1" />
 <TextView4
     app:layout_constraintHorizontal_weight="1" />

inserisci qui la descrizione dell'immagine

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.