Comment centrer les éléments dans ConstraintLayout

205

J'utilise ConstraintLayoutdans mon application pour faire la mise en page des applications. J'essaie de créer un écran où un EditTextet Buttondevrait être au centre et Buttondevrait être en dessous de EditTextavec un marginTop seulement 16dp.

Voici ma mise en page et capture d'écran à quoi cela ressemble en ce moment.

activity_authenticate_content.xml

<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:paddingLeft="16dp"
    android:paddingRight="16dp"
    tools:context="com.icici.iciciappathon.login.AuthenticationActivity">

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

        <android.support.design.widget.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/login_client_id"
            android:inputType="textEmailAddress" />

    </android.support.design.widget.TextInputLayout>

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/authenticate"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="@string/login_auth"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="@id/client_id_input_layout"
        app:layout_constraintRight_toRightOf="@id/client_id_input_layout"
        app:layout_constraintTop_toTopOf="@id/client_id_input_layout" />

</android.support.constraint.ConstraintLayout>

entrez la description de l'image ici

N Sharma
la source

Réponses:

145

Mettre à jour:

Chaîne

Vous pouvez maintenant utiliser la chainfonctionnalité en packedmode comme décrit dans la réponse d'Eugene.


Ligne directrice

Vous pouvez utiliser une ligne directrice horizontale à 50% et ajouter des contraintes inférieure et supérieure (8dp) à edittext et au bouton:

<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:paddingLeft="16dp"
    android:paddingRight="16dp">

    <android.support.design.widget.TextInputLayout
        android:id="@+id/client_id_input_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent">

        <android.support.design.widget.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/login_client_id"
            android:inputType="textEmailAddress"/>

    </android.support.design.widget.TextInputLayout>

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/authenticate"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/login_auth"
        app:layout_constraintTop_toTopOf="@+id/guideline"
        android:layout_marginTop="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"/>

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

</android.support.constraint.ConstraintLayout>

Éditeur de mise en page

Pycpik
la source
1
Merci @Pycpik, je ne pouvais pas comprendre à quoi sert <android.support.constraint.Guideline? Avons-nous besoin d'utiliser à chaque fois que nous utilisons ConstraintLayout?
N Sharma
À quoi ça sert layout_constraintGuide_percent?
N Sharma
1
Guidelineest juste un élément invisible sur lequel vous pouvez ancrer vos vues. layout_constraintGuide_percentest le pourcentage dans le parent. Ici 0,5 est une hauteur de 50%
Pycpik
Merci. Je t'ai eu. J'en ai maintenant deux TextInputEditTextet un Button. Je veux les placer au centre de l'écran. Mais pour l'instant ce n'est pas pastebin.com/iXYtuXHg voici la capture d'écran dropbox.com/s/k7997q2buvw76cp/q.png?dl=0
N Sharma
1
Vous pouvez centrer celui du milieu et en ajouter un au-dessus et un en dessous ou les mettre dans un LinearLayoutet le centrer.
Pycpik
332

Il existe un moyen plus simple. Si vous définissez les contraintes de disposition comme suit et que votre EditText est de taille fixe, il sera centré dans la disposition des contraintes:

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

La paire gauche / droite centre la vue horizontalement et la paire haut / bas la centre verticalement. En effet, lorsque vous définissez les contraintes gauche, droite ou supérieure, inférieure plus grandes que la vue elle-même, la vue est centrée entre les deux contraintes, c'est-à-dire que le biais est défini sur 50%. Vous pouvez également déplacer la vue vers le haut / bas ou la droite / gauche en définissant le biais vous-même. Jouez un peu avec et vous verrez comment cela affecte la position des vues.

binW
la source
5
C'est une bien meilleure approche que l'utilisation de directives.
ssand
48
app:layout_constraintCenter_in="parent"serait bien mieux. Mais comme toujours, Google ne l'a pas fourni.
Gojir4
1
C'est plus approprié et je l'ai également vu dans de nombreux entretiens et exemples de responsables.
TapanHP
Simple, facile à comprendre.
Yohanes AI
2
Les directives sont meilleures car une fois que vous avez une mise en page complexe, ce qui se produira une fois que le marketing s'en emparera, le centrage simpliste ne fonctionnera plus. Mieux vaut avoir des lignes directrices et centrer la ligne directrice pour le haut et le bas
Nick Turner
58

La solution avec directive ne fonctionne que dans ce cas particulier avec EditText sur une seule ligne. Pour le faire fonctionner pour EditText multiligne, vous devez utiliser une chaîne "compactée".

<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"
    android:paddingLeft="16dp"
    android:paddingRight="16dp">

    <android.support.design.widget.TextInputLayout
        android:id="@+id/client_id_input_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/authenticate"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed">

        <android.support.design.widget.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/login_client_id"
            android:inputType="textEmailAddress" />

    </android.support.design.widget.TextInputLayout>

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/authenticate"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="@string/login_auth"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="@id/client_id_input_layout"
        app:layout_constraintRight_toRightOf="@id/client_id_input_layout"
        app:layout_constraintTop_toBottomOf="@id/client_id_input_layout" />

</android.support.constraint.ConstraintLayout>

Voici à quoi ça ressemble:

Vue sur Nexus 5

Vous pouvez en savoir plus sur l'utilisation des chaînes dans les articles suivants:

Eugene Brusov
la source
C'est certainement la meilleure réponse. Les autres réponses ne fonctionnent que pour une ou deux vues. Celui-ci est plus évolutif, car il fonctionne pour une, deux et autant de vues que vous le souhaitez.
mdelolmo
21

Vous pouvez centrer une vue en pourcentage de la taille de l'écran.

Cet exemple utilise 50% de la largeur et de la hauteur:

<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="#FF0000"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_percent=".5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent=".5"></LinearLayout>

</android.support.constraint.ConstraintLayout>

Cela a été fait en utilisant ConstraintLayout version 1.1.3. N'oubliez pas de l'ajouter à vos dépendances dans le gradle et d'augmenter la version s'il y en a une nouvelle:

dependencies {
...
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}

entrez la description de l'image ici

l'amour en direct
la source
12

ajoutez ces balises dans votre vue

    app:layout_constraintCircleRadius="0dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.5"
    app:layout_constraintStart_toStartOf="parent"

et vous pouvez faire un clic droit en mode conception et choisir le centre.

behrad
la source
8

vous pouvez utiliser layout_constraintCircle pour une vue centrale à l'intérieur de ConstraintLayout.

<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:id="@+id/mparent"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageButton
            android:id="@+id/btn_settings"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/ic_home_black_24dp"
            app:layout_constraintCircle="@id/mparent"
            app:layout_constraintCircleRadius="0dp"
            />
    </android.support.constraint.ConstraintLayout>

avec constraintCircle au parent et un rayon nul, vous pouvez faire de votre vue le centre du parent.

Enakhi
la source
best.solution.ever. Tout comme une "app: layout_constraintCenter_in =" parent "" (qui n'existe pas)
Bénédicte Lagouge