22. Mar 2021
AndroidAll about Constraint Layout helpers I.
Constraint layout is type of ViewGroup, which allows you to create complex layouts with flat view hierarchy. Full power of CL comes from his helpers.
Group
The simplest of Constraint Layout helpers. Just controls visibility of multiple (or one) referenced views. Tends to be useful if you want to set multiple views to VISIBLE or GONE state, but don't want to wrap them in some ViewGroup wrapper so your XML structure can stay flat.
For referencing views inside Group constraint_referenced_ids attribute can be used.
app:constraint_referenced_ids="text,button"
app:constraint_referenced_ids="text,button"
In the following example, text's and button's visibility can be controlled by setting visibility to Group helper. E.g.
//Doing this somewhere in code shows text and button
group.visibility = View.VISIBLE
//Doing this somewhere in code hides text and button
group.visibility = View.GONE
<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">
<androidx.constraintlayout.widget.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="text,button"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android Text"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android"
app:layout_constraintTop_toBottomOf="@id/text"/>
</androidx.constraintlayout.widget.ConstraintLayout>
In case where one view is referenced from multiple groups, the declaration order in XML will define the final visibility (last group in XML has last word).
Layer
Practically the same as Group helper, but changes of translation, scale and rotation are supported.
E.g. rotating multiple views can look like this
image1.setOnClickListener { layer.rotation = Random.nextInt(60).toFloat()}
<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">
<ImageView
android:id="@+id/image1"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@drawable/background_badge_green"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/image2"/>
<ImageView
android:id="@+id/image2"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@drawable/background_badge_red"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/image1"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.constraintlayout.helper.widget.Layer
android:id="@+id/layer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="image1, image2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Guideline
Invisible helper object for Constraint Layout (it's never displayed on device). Main purpose of guideline is to place the child of Constraint Layout at some specific location (e.g. 100dp from screen start or 25% from screen bottom...)
Guideline can be either Vertical (zero width, height of parent Constraint Layout) or Horizontal(width of parent Constraint Layout, zero height). You can use orientation attribute for defining orientation of Guideline.
android:orientation="vertical"
OR
android:orientation="horizontal"
The most important property of Guideline is it's position. Guideline can be positioned in 3 different ways using layout_constraintGuide_begin, layout_constraintGuide_end and layout_constraintGuide_percent attributes. These are affected by orientation also.
//100dp from start
android:orientation="vertical"
app:layout_constraintGuide_begin="100dp"
OR
//100dp from bottom
android:orientation="horizontal"
app:layout_constraintGuide_end="100dp"
OR
//14% from top
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.14"
Any direct child of Constraint Layout can be constrained to Guideline, but Guideline on it's own cannot have any constraints. Position of guidelines is only determined by mentioned attributes. Here is the example of Button positioned to 25% from top 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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.25" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android"
app:layout_constraintTop_toTopOf="@id/guideline"
app:layout_constraintBottom_toBottomOf="@id/guideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Barrier
Barrier helper is similar to Guideline. Main difference between them is that the Barrier is flexible. It takes multiple views in constraint_referenced_ids attribute and creates virtual guideline based on the most extreme view from referenced views (most extreme view is the widest or the highest view). If width (or height) of most extreme view changes during runtime, barrier will automatically move according to it. Every Barrier needs to have barrierDirection attribute.
app:barrierDirection="start" //Barrier is positioned at the start of referenced views
app:barrierDirection="end" //Barrier is positioned at the end referenced views
app:barrierDirection="top" //Barrier is positioned above referenced views
app:barrierDirection="bottom" //Barrier is positioned below referenced views
Barrier tends to be useful when you want to constraint view below (or above, at the end, at the start) of another views. E.g. usecase, when button needs to be under textViews, no matter how long they are.You should notice that, you can constraint views to Barrier (unlike to Guideline).
<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">
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="text1,text2" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Android Text"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/text2"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Android Text slightly wider Android Text slightly wider"
app:layout_constraintStart_toEndOf="@id/text1"
app:layout_constraintEnd_toEndOf="parent"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/barrier"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Did you like this article? Read more in the second part! Follow me on LinkedIn and stay in track.