Android Constraint Layout
Here's a short tutorial on how to use ConstraintLayout
in Android.
Recommended reading
The reading below on this page is intended to just be an introduction to ConstraintLayout
, and not a complete description of how to use all the functionality it contains. For all details about how to use it, check out the documentation for ConstraintLayout
.
ConstraintLayout
The ConstraintLayout
is a layout in which the children can be positioned relative to each other (a child can be positioned below another child, or above another child, or to the right of another child, etc.), or relative to the parent's edges (below the parent's top edge, or above the parent's bottom edge, or to the right of the parent's left edge, etc.). It is very similar to the RelativeLayout, but offers more functionality.
The ConstraintLayout
is not part of the Android framework, but developed by Google in a separate library that is part of Android Jetpack. To add the library to your Android Studio Project, follow the instructions at the Declaring dependencies section.
Use the correct namespace!
Since the ConstraintLayout
is not part of the Android framework, it does not put its own specific attributes in the XML namespace http://schemas.android.com/apk/res/android
(usually called android
), but instead in the namespace http://schemas.android.com/apk/res-auto
, which one usually call app
.
A child in ConstraintLayout
can have layout_width
and layout_height
set to wrap_content
/match_parent
, in which case the child will have the size specified by these two attributes (as usual).
Example
Example showing how to add two View
s to a ConstraintLayout
.
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#0000ff"
android:text="Text 2" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
In the example above, we haven't told the ConstraintLayout
where the children should be positioned, so both TextView
s are positioned in top left corner by default (that's why we can't see the first TextView
; it's behind the second TextView
!).
To tell the ConstraintLayout
where a child should be positioned horizontally, we can add one of the following attributes (known as a constraint) to the child:
app:layout_constraintLeft_toLeftOf
app:layout_constraintLeft_toRightOf
app:layout_constraintRight_toLeftOf
app:layout_constraintRight_toRightOf
The value can either be parent
, or the id of one of the other child View
s in the ConstraintLayout
.
Similarly, to tell the ConstraintLayout
where a child should be positioned vertically, we can add one of the following attributes to the child:
app:layout_constraintTop_toTopOf
app:layout_constraintTop_toBottomOf
app:layout_constraintBottom_toTopOf
app:layout_constraintBottom_toBottomOf
The value can either be parent
, or the id of one of the other child View
s in the ConstraintLayout
.
Supporting Right-to-Left devices
To support layouts for people reading from right to left, use Start
instead of Left
and End
instead of Right
in the attribute names, e.g. use layout_constraintStart_toEndOf
instead of layout_constraintLeft_toRightOf
.
Example
Example showing how to position one View
in the top right corner, and another View
in the bottom left corner.
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:background="#0000ff"
android:text="Text 2" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
Example
Example showing how to position two View
s in the top right corner (one below the other).
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/first_text_view"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/first_text_view"
app:layout_constraintRight_toRightOf="parent"
android:background="#0000ff"
android:text="Text 2" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
Example
Example showing how to position two View
s diagonally in the top right corner.
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/first_text_view"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/first_text_view"
app:layout_constraintRight_toLeftOf="@id/first_text_view"
android:background="#0000ff"
android:text="Text 2" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
Repetition
To tell the ConstraintLayout
where a child should be positioned horizontally, we can add one of the following attributes (known as a constraint) to the child:
app:layout_constraintLeft_toLeftOf
app:layout_constraintLeft_toRightOf
app:layout_constraintRight_toLeftOf
app:layout_constraintRight_toRightOf
The value can either be parent
, or the id of one of the other child View
s in the ConstraintLayout
.
Similarly, to tell the ConstraintLayout
where a child should be positioned vertically, we can add one of the following attributes to the child:
app:layout_constraintTop_toTopOf
app:layout_constraintTop_toBottomOf
app:layout_constraintBottom_toTopOf
app:layout_constraintBottom_toBottomOf
The value can either be parent
, or the id of one of the other child View
s in the ConstraintLayout
.
Instead of giving a child it's size through the layout_width
and layout_height
attributes, you can specify two horizontal (or two vertical) constraints, and the child can get its width (or height) from the constraints instead. When a child has two horizontal constraints (or two vertical constraints) and you want the child to get its size through the constraints you should set the layout_width
(or layout_height
) to 0dp
.
Example
Example showing how to position two View
s next to each other horizontally:
- The first one is as small as possible
- The second one should occupy the rest of the remaining space
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/first_text_view"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/first_text_view"
app:layout_constraintRight_toRightOf="parent"
android:background="#0000ff"
android:text="Text 2" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
If a child has a size smaller than what is specified by two horizontal/vertical constraints, the child will be centered instead of growing to cover the space.
Example
Example showing how to position two View
s next to each other, and center the second View
in the rest of the available space.
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/first_text_view"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/first_text_view"
app:layout_constraintRight_toRightOf="parent"
android:background="#0000ff"
android:text="Text 2" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
To control where in the rest of the available space the child is positioned (center by default), use the app:layout_constraintHorizontal_bias
/app:layout_constraintVertical_bias
attribute. The value is number between 0
and 1
, where:
0
means at the start- ...
0.5
means in the middle (default)- ...
1
means at the end
Example
Example showing how to position two View
s next to each other, and placing the second View
90% to the right of the rest of the available space.
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/first_text_view"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/first_text_view"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.9"
android:background="#0000ff"
android:text="Text 2" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
When you have a multiple children getting their sizes from the constraints in the same "chain", they by default get an equal amount of the remaining space available.
Example
Example showing how to position three View
s next to each other, and let the last two share the remaining available space equally.
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/first_text_view"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/first_text_view"
app:layout_constraintRight_toLeftOf="@id/third_text_view"
android:id="@+id/second_text_view"
android:background="#0000ff"
android:text="Text 2" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/second_text_view"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/third_text_view"
android:background="#ffff00"
android:text="Text 3" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
If you want the remaining space to be distributed differently among the children, you can use the attribute layout_constraintHorizontal_weight
/layout_constraintVertical_weight
to indicate how many shares of the remaining vertical space they should occupy.
Example
Example showing how to position three View
s next to each other, and let the second occupy one third of the remaining space, and the third to occupy 2 thirds of the remaining space.
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/first_text_view"
android:background="#00ff00"
android:text="Text 1" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/first_text_view"
app:layout_constraintRight_toLeftOf="@id/third_text_view"
app:layout_constraintHorizontal_weight="1"
android:id="@+id/second_text_view"
android:background="#0000ff"
android:text="Text 2" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/second_text_view"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_weight="2"
android:id="@+id/third_text_view"
android:background="#ffff00"
android:text="Text 3" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}
Bigger example
Example
Example showing how to use a <ConstraintLayout>
to implement a layout with main content and a row with 3 navigation buttons at the bottom.
<androidx.constraintlayout.widget.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:background="#ff0000">
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/first_button"
app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/main_content_text_view"
android:background="#00ff00"
android:gravity="center"
android:text="I'm the main content!" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/main_content_text_view"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/second_button"
android:id="@+id/first_button"
android:text="Page 1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/main_content_text_view"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/first_button"
app:layout_constraintRight_toLeftOf="@id/third_button"
android:id="@+id/second_button"
android:text="Page 2" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/main_content_text_view"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/second_button"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/third_button"
android:text="Page 3" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.app.Activity
import android.os.Bundle
class MyActivity : Activity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
}
}