web-dev-qa-db-fra.com

Espacement régulier des vues avec ConstraintLayout

Une utilisation courante de LinearLayout consiste à espacer uniformément les vues (pondérées), par exemple: example layout

Comment implémentez-vous des vues espacées de manière uniforme comme celle-ci en utilisant le nouveau ConstraintLayout?

Liens ConstraintLayout pour référence: article de blog , vidéo de session d'E/S

144
AdamK

Pour ce faire, vous pouvez utiliser ConstraintLayout: Chaînes et Instructions . Pour utiliser les chaînes, assurez-vous que vous utilisez ConstraintLayout Bêta 3 ou plus récente et si vous souhaitez utiliser l'éditeur de disposition visuelle dans Android Studio, assurez-vous d'utiliser Android. Studio 2.3 Beta 1 ou plus récent.

Méthode 1 - Utiliser les chaînes

Ouvrez l'éditeur de disposition et ajoutez vos widgets normalement, en ajoutant des contraintes parent si nécessaire. Dans ce cas, j'ai ajouté deux boutons avec des contraintes au bas du parent et du côté du parent (côté gauche pour le bouton Enregistrer et côté droit pour le bouton Partager):

enter image description here

Notez que dans cet état, si je bascule en mode paysage, les vues ne remplissent pas le parent, mais sont ancrées aux coins:

enter image description here

Mettez en surbrillance les deux vues, soit en cliquant sur Ctrl/Cmd, soit en faisant glisser un cadre autour de la vue:

enter image description here

Puis cliquez avec le bouton droit sur les vues et choisissez "Centrer horizontalement":

enter image description here

Ceci établit une connexion bidirectionnelle entre les vues (c'est comment une chaîne est définie). Par défaut, le style de chaîne est "spread", qui s'applique même lorsqu'aucun attribut XML n'est inclus. Si vous vous en tenez à ce style de chaîne mais en définissant la largeur de nos vues sur 0dp, les vues remplissent l’espace disponible et se répartissent uniformément sur le parent:

enter image description here

Ceci est plus visible en mode paysage:

enter image description here

Si vous préférez ignorer l'éditeur de présentation, le code XML obtenu se présentera comme suit:

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

Détails:

  • définir la largeur de chaque élément sur 0dp ou MATCH_CONSTRAINT permet aux vues de remplir le parent (facultatif)
  • les vues doivent être liées entre elles de manière bidirectionnelle (à droite des liens du bouton Enregistrer pour partager le bouton, à gauche des liens du bouton Partager pour enregistrer le bouton), cela se produira automatiquement via l'éditeur de présentation lors du choix de "Centrer horizontalement".
  • la première vue de la chaîne peut spécifier le style de chaîne via layout_constraintHorizontal_chainStyle, voir documentation pour différents styles de chaîne, si le style de chaîne est omis, la valeur par défaut est "spread"
  • la pondération de la chaîne peut être ajustée via layout_constraintHorizontal_weight
  • cet exemple concerne une chaîne horizontale, il existe des attributs correspondants pour les chaînes verticales

Méthode 2 - Utiliser une ligne directrice

Ouvrez votre mise en page dans l'éditeur et cliquez sur le bouton guide:

enter image description here

Puis sélectionnez "Ajouter un repère vertical": enter image description here

Une nouvelle ligne directrice apparaîtra qui, par défaut, sera probablement ancrée à gauche dans les valeurs relatives (indiquées par la flèche orientée vers la gauche):

layout editor relative guideline

Cliquez sur la flèche orientée vers la gauche pour la convertir en pourcentage, puis faites glisser la ligne de guidage jusqu'au repère 50%:

layout editor percent guideline

La ligne directrice peut maintenant être utilisée comme point d'ancrage pour d'autres vues. Dans mon exemple, j'ai attaché la droite du bouton de sauvegarde et la gauche du bouton de partage à la ligne directrice:

final layout

Si vous souhaitez que les vues occupent tout l'espace disponible, la contrainte doit être définie sur "N'importe quelle taille" (les lignes ondulées horizontales):

any size constraint

(Cela revient à régler le layout_width sur 0dp).

Un guide peut également être créé assez facilement en XML plutôt que d'utiliser l'éditeur de disposition:

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

Bien si ça aide quelqu'un

le clé est ici app:layout_constraintHorizontal_weight="1" et
La meilleure chose à propos de la configuration des contraintes est qu’elle prend en charge la dépendance circulaire et c’est ce que j’ai fait exactement en utilisant cela.

Pour le premier enfant
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"

pour le deuxième enfant

app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"

voici la démo complète

<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>
23
rookieDeveloper

Pour créer 2 vues dans la même ligne, de largeur égale, il suffit de définir

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

Note

  • width = 0dp (MATCH_CONSTRAINT)
  • La contrainte de button1 et button2 doit être comme ci-dessus

Résultat

PLUS
Si vous voulez View1 plus grand que View2, vous pouvez utiliser weight ou percent.
Exemple, View1 width = 2 * View2 width use weight

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

Résultat

Exemple, View1 width = 2 * View2 width use pourcent

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

Résultat

22
Phan Van Linh

Vous devriez lire sur les chaînes pondérées. Un exemple de code est ici.

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

Donc, définissez Android:layout_width="0dp", app:layout_constraintHorizontal_weight="1" et liez toutes les vues avec des voisins tels que:

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

enter image description here

9
CoolMind