Constraint Layout Vertical Align Center
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:
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:
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>
Solution 1:
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)
Solution 2:
If you have a ConstraintLayout
with some size, and a child View
with some smaller size, you can achieve centering by constraining the child's two edges to the same two edges of the parent. That is, you can write:
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
or
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
Because the view is smaller, these constraints are impossible. But ConstraintLayout
will do the best it can, and each constraint will "pull" at the child view equally, thereby centering it.
This concept works with any target view, not just the parent.
Update
Below is XML that achieves your desired UI with no nesting of views and no Guideline
s (though guidelines are not inherently evil).
<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="wrap_content"
android:background="#eee">
<TextView
android:id="@+id/title1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:gravity="center"
android:textColor="#777"
android:textSize="22sp"
android:text="10"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/divider1"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/label1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#777"
android:textSize="12sp"
android:text="Streak"
app:layout_constraintTop_toBottomOf="@+id/title1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/divider1"/>
<View
android:id="@+id/divider1"
android:layout_width="1dp"
android:layout_height="55dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:background="#ccc"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/title1"
app:layout_constraintRight_toLeftOf="@+id/title2"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:gravity="center"
android:textColor="#777"
android:textSize="22sp"
android:text="243"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/divider1"
app:layout_constraintRight_toLeftOf="@+id/divider2"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/label2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#777"
android:textSize="12sp"
android:text="Calories Burned"
app:layout_constraintTop_toBottomOf="@+id/title2"
app:layout_constraintLeft_toRightOf="@+id/divider1"
app:layout_constraintRight_toLeftOf="@+id/divider2"/>
<View
android:id="@+id/divider2"
android:layout_width="1dp"
android:layout_height="55dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:background="#ccc"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/title2"
app:layout_constraintRight_toLeftOf="@+id/title3"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/title3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:gravity="center"
android:textColor="#777"
android:textSize="22sp"
android:text="3200"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/divider2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/label3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#777"
android:textSize="12sp"
android:text="Steps"
app:layout_constraintTop_toBottomOf="@+id/title3"
app:layout_constraintLeft_toRightOf="@+id/divider2"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
Solution 3:
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">
Last two lines did the trick!
Solution 4:
<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"/>