Constraint Layout Vertical Align Center

Viewed 188804

How to vertically align and center objects in constraint layout? It is possible to align vertically or horizontally but I have not found a way to center at the same time beside constraining the views between two gridlines.

Vertical Align Center: enter image description here

It seems like centering is a huge problem with constraint layout which forces me to go back to relative layout for "centerInParent", "centerVertical", and "centerHorizontal".

I would like to create the layout boxed in red using constraint layout: enter image description here

Unfortunately, the only way I found without using two gridlines is with nested Relative and LinearLayouts (which Constraint Layout was supposed to solve this exact scenario!).

Layout using Relative and Linear Layout:

<RelativeLayout
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="12dp"
    app:layout_constraintTop_toBottomOf="@id/user_points"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent">

    <LinearLayout
        android:id="@+id/stat_1_layout"
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="12dp"
        android:layout_marginRight="12dp"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/divider_1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/stat_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal"
            android:text="10"
            android:textSize="16dp"
            android:textColor="@color/textSecondaryDark"
            android:maxLines="1"/>

        <TextView
            android:id="@+id/stat_detail_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:gravity="center"
            android:text="Streak"
            android:textSize="8sp"
            android:textColor="@color/textSecondary"
            android:maxLines="1"/>
    </LinearLayout>

    <View
        android:id="@+id/divider_1"
        android:layout_width="1dp"
        android:layout_height="38dp"
        android:layout_toLeftOf="@+id/stat_2_layout"
        android:background="@drawable/linedivider"/>

    <LinearLayout
        android:id="@+id/stat_2_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="18dp"
        android:layout_marginRight="18dp"
        android:layout_centerInParent="true"
        android:orientation="vertical">

        <TextView
            android:id="@+id/stat_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal"
            android:text="243"
            android:textSize="16dp"
            android:textColor="@color/textSecondaryDark"
            android:maxLines="1"/>

        <TextView
            android:id="@+id/stat_detail_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:gravity="center"
            android:text="Calories Burned"
            android:textSize="8sp"
            android:textColor="@color/textSecondary"
            android:maxLines="1"/>
    </LinearLayout>

    <View
        android:id="@+id/divider_2"
        android:layout_width="1dp"
        android:layout_height="38dp"
        android:layout_toRightOf="@+id/stat_2_layout"
        android:background="@drawable/linedivider"/>

    <LinearLayout
        android:id="@+id/stat_3_layout"
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="12dp"
        android:layout_marginRight="12dp"
        android:layout_toRightOf="@+id/divider_2"
        android:layout_centerVertical="true"
        android:orientation="vertical">

        <TextView
            android:id="@+id/stat_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal"
            android:text="3200"
            android:textSize="16dp"
            android:textColor="@color/textSecondaryDark"
            android:maxLines="1"/>

        <TextView
            android:id="@+id/stat_detail_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:gravity="center"
            android:text="Steps"
            android:textSize="8sp"
            android:textColor="@color/textSecondary"
            android:maxLines="1"/>
    </LinearLayout>
</RelativeLayout>
7 Answers

It's possible to set the center aligned view as an anchor for other views. In the example below "@+id/stat_2" centered horizontally in parent and it serves as an anchor for other views in this layout.

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

    <TextView
        android:id="@+id/stat_1"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:gravity="center"
        android:maxLines="1"
        android:text="10"
        android:textColor="#777"
        android:textSize="22sp"
        app:layout_constraintTop_toTopOf="@+id/stat_2"
        app:layout_constraintEnd_toStartOf="@+id/divider_1" />

    <TextView
        android:id="@+id/stat_detail_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Streak"
        android:textColor="#777"
        android:textSize="12sp"
        app:layout_constraintTop_toBottomOf="@+id/stat_1"
        app:layout_constraintStart_toStartOf="@+id/stat_1"
        app:layout_constraintEnd_toEndOf="@+id/stat_1" />

    <View
        android:id="@+id/divider_1"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:layout_marginEnd="16dp"
        android:background="#ccc"
        app:layout_constraintTop_toTopOf="@+id/stat_2"
        app:layout_constraintEnd_toStartOf="@+id/stat_2"
        app:layout_constraintBottom_toBottomOf="@+id/stat_detail_2" />

    <TextView
        android:id="@+id/stat_2"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:maxLines="1"
        android:text="243"
        android:textColor="#777"
        android:textSize="22sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <TextView
        android:id="@+id/stat_detail_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:text="Calories Burned"
        android:textColor="#777"
        android:textSize="12sp"
        app:layout_constraintTop_toBottomOf="@+id/stat_2"
        app:layout_constraintStart_toStartOf="@+id/stat_2"
        app:layout_constraintEnd_toEndOf="@+id/stat_2" />

    <View
        android:id="@+id/divider_2"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:background="#ccc"
        app:layout_constraintBottom_toBottomOf="@+id/stat_detail_2"
        app:layout_constraintStart_toEndOf="@+id/stat_2"
        app:layout_constraintTop_toTopOf="@+id/stat_2" />

    <TextView
        android:id="@+id/stat_3"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:gravity="center"
        android:maxLines="1"
        android:text="3200"
        android:textColor="#777"
        android:textSize="22sp"
        app:layout_constraintTop_toTopOf="@+id/stat_2"
        app:layout_constraintStart_toEndOf="@+id/divider_2" />

    <TextView
        android:id="@+id/stat_detail_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:text="Steps"
        android:textColor="#777"
        android:textSize="12sp"
        app:layout_constraintTop_toBottomOf="@+id/stat_3"
        app:layout_constraintStart_toStartOf="@+id/stat_3"
        app:layout_constraintEnd_toEndOf="@+id/stat_3" />

</android.support.constraint.ConstraintLayout>

Here's how it works on smallest smartphone (3.7 480x800 Nexus One) vs largest smartphone (5.5 1440x2560 Pixel XL)

Result view

May be i did not fully understand the problem, but, centering all view inside a ConstraintLayout seems very simple. This is what I used:

<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"
android:layout_gravity="center">

enter image description here

Last two lines did the trick!

 <TextView
        android:id="@+id/tvName"
        style="@style/textViewBoldLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="Welcome"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

I also had a requirement something similar to it. I wanted to have a container in the center of the screen and inside the container there are many views. Following is the xml layout code. Here i'm using nested constraint layout to create container in the center of the screen.

        <androidx.constraintlayout.widget.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:background="@drawable/gradient_background"
    tools:context=".activities.AppInfoActivity">

    <ImageView
        android:id="@+id/ivClose"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:src="@drawable/ic_round_close_24"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="300dp"
        android:layout_height="300dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5">

        <ImageView
            android:id="@+id/ivAppIcon"
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/dead" />

        <TextView
            android:id="@+id/tvAppName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Birds Shooter Plane"
            android:textAlignment="center"
            android:textSize="30sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/ivAppIcon" />

        <TextView
            android:id="@+id/tvAppVersion"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Version : 1.0"
            android:textAlignment="center"
            android:textSize="12sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvAppName" />

        <TextView
            android:id="@+id/tvDevelopedBy"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="25dp"
            android:text="Developed by"
            android:textAlignment="center"
            android:textSize="12sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvAppVersion" />

        <TextView
            android:id="@+id/tvDevelopedName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:text="K Pradeep Kumar Reddy"
            android:textAlignment="center"
            android:textSize="14sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvDevelopedBy" />

        <TextView
            android:id="@+id/tvContact"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:text="Contact : kpradeepkumarreddy@gmail.com"
            android:textAlignment="center"
            android:textSize="12sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvDevelopedName" />

        <TextView
            android:id="@+id/tvCheckForUpdate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="25dp"
            android:text="@string/check_for_update"
            android:textAlignment="center"
            android:textSize="14sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvContact" />
    </androidx.constraintlayout.widget.ConstraintLayout>
  </androidx.constraintlayout.widget.ConstraintLayout>

Here is the screenshot of the layout enter image description here

Other solution is to remove the nested constraint layout and add constraint_vertical_bias = 0.5 attribute to the top element in the center of layout. I think this is called as chaining of views.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:background="@drawable/gradient_background"
tools:context=".activities.AppInfoActivity">

<ImageView
android:id="@+id/ivClose"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/ic_round_close_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/ivAppIcon"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5"
app:srcCompat="@drawable/dead" />

<TextView
android:id="@+id/tvAppName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_display_name"
android:textAlignment="center"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ivAppIcon" />

<TextView
android:id="@+id/tvAppVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/version"
android:textAlignment="center"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvAppName" />

<TextView
android:id="@+id/tvDevelopedBy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:text="@string/developed_by"
android:textAlignment="center"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvAppVersion" />

<TextView
android:id="@+id/tvDevelopedName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="@string/developer_name"
android:textAlignment="center"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvDevelopedBy" />

<TextView
android:id="@+id/tvContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="@string/developer_email"
android:textAlignment="center"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvDevelopedName" />
<TextView
android:id="@+id/tvCheckForUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:text="@string/check_for_update"
android:textAlignment="center"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvContact" />
</androidx.constraintlayout.widget.ConstraintLayout>

Here is the screenshot of the layout enter image description here

Related