ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Follow publication

Android ConstraintLayout explained using a complex UI

ConstraintLayout is introduced to build very complex and responsive UI for your app. Previously for building any complex UI I was using RelativeLayout till I came across this complex UI

Above screenshot is footer of a fragment in app footer describes login process steps and on which step user is currently. There are three steps to complete login

  • Enter mobile number
  • OTP
  • Profile

and user currently on first step which is to enter mobile number.

Now take few minutes and try building above UI using RelativeLayout or any other layout and see how it goes, do let me know in comments if anyone able to build exact using layout other than ConstraintLayout.

Those who are new to ConstraintLayout consider reading following first

https://developer.android.com/training/constraint-layout/

Let’s start

First add gradle dependency to your project.

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

To explain it further let me show you how UI looks in design view in android studio

Building this UI was possible using Guidelines. Guidelines are noting but virtual view they are not visible as such they can be viewed in design preview and blueprints in above image you can see I have used two guidelines two dotted lines that can be seen in the centre vertically and horizontally are nothing but guidelines.

After adding guideline this is how xml looks

<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="80dp"
android:paddingBottom="8dp"
>

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

Now app:layout_constraintGuide_percent=”0.5" this defines where do you want the guideline exactly in my case I wanted in centre so value is 0.5. Suppose you cant to want to add a textview horizontally exactly after 3/4th width of screen you will add a vertical guideline yes don’t get confuse vertical since we are dividing screen horizontally we will use vertical guideline and guideline will look as below

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

Hope everyone got an idea about guideline lets get back to the original problem now.

After adding two guidelines one horizontally and one vertically exactly at centre let’s add first UI element.

First will add ImageView exactly in centre of guidelines following is code

<ImageView
android:id="@+id/ivotp"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginTop="8dp"
android:background="@drawable/otp_process_circle"
app:layout_constraintBottom_toTopOf="@+id/guideline1"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="@+id/guideline1"
/>

Following code is for placing ImageView exact in centre with respect to horizontal guideline

app:layout_constraintBottom_toTopOf="@+id/guideline1" 
app:layout_constraintTop_toTopOf="@+id/guideline1"

and below code to place ImageView exact in centre with respect to vertical guideline

app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintStart_toStartOf="@+id/guideline"

Now to the left and right of this ImageView we will add dividers as required in UI

<ImageView
android:id="@+id/ivseconddiv"
android:layout_width="76dp"
android:layout_height="2dp"
android:background="@drawable/stroke_divider"
android:layerType="software"
app:layout_constraintBottom_toBottomOf="@+id/ivotp"
app:layout_constraintStart_toEndOf="@+id/ivotp"
app:layout_constraintTop_toTopOf="@+id/ivotp"
/>
<ImageView
android:id="@+id/ivfirstdiv"
android:layout_width="76dp"
android:layout_height="2dp"
android:layerType="software"
android:src="@drawable/stroke_divider"
app:layout_constraintBottom_toBottomOf="@+id/ivotp"
app:layout_constraintEnd_toStartOf="@+id/ivotp"
app:layout_constraintTop_toTopOf="@+id/ivotp"
/>

Below lines are placing divider exact in vertical centre with respect to ImageView ivotp

app:layout_constraintBottom_toBottomOf and app:layout_constraintTop_toTopOf

this is how our UI will look now

Now at the end of these dividers we will add two ImageViews as below

<ImageView
android:id="@+id/ivnumberfill"
android:layout_width="16dp"
android:layout_height="16dp"
app:layout_constraintBottom_toBottomOf="@+id/ivfirstdiv"
app:layout_constraintEnd_toStartOf="@+id/ivfirstdiv"
app:layout_constraintTop_toTopOf="@+id/ivfirstdiv"
app:srcCompat="@drawable/ic_otp_fill"
/>
<ImageView
android:id="@+id/ivprofile"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_toRightOf="@+id/ivseconddiv"
android:background="@drawable/otp_process_circle"
app:layout_constraintBottom_toBottomOf="@+id/ivseconddiv"
app:layout_constraintStart_toEndOf="@+id/ivseconddiv"
app:layout_constraintTop_toTopOf="@+id/ivseconddiv"
/>

This is how our UI will look now

Now we just need to add three TextView below each circle ImageViews exactly at the horizontal centre following is code to add it

<TextView
android:id="@+id/tvnumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ivnumberfill"
android:layout_marginTop="4dp"
android:text="Mobile Number"
android:textColor="?colorAccent"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="@id/ivnumberfill"
app:layout_constraintStart_toStartOf="@id/ivnumberfill"
app:layout_constraintTop_toBottomOf="@id/ivnumberfill"
/>
<TextView
android:id="@+id/tvotp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ivnumberfill"
android:layout_marginTop="8dp"
android:text="OTP"
android:textColor="#949595"
android:textSize="11sp"
app:layout_constraintEnd_toStartOf="@+id/ivseconddiv"
app:layout_constraintStart_toStartOf="@+id/ivotp"
app:layout_constraintTop_toBottomOf="@+id/ivotp"
/>
<TextView
android:id="@+id/tvprofile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ivnumberfill"
android:layout_marginTop="8dp"
android:text="Profile"
android:textColor="#949595"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="@+id/ivprofile"
app:layout_constraintStart_toStartOf="@+id/ivprofile"
app:layout_constraintTop_toBottomOf="@+id/ivprofile"
/>

In above code app:layout_constraintEnd_toEndOf and app:layout_constraintStart_toStartOf will align text center horizontally with respect to imageview and app:layout_constraintTop_toBottomOf this will align text below ImageView.

So here is our final UI and final xml code

<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="80dp"
android:paddingBottom="8dp"
>
<ImageView
android:id="@+id/ivotp"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginTop="8dp"
android:background="@drawable/otp_process_circle"
app:layout_constraintBottom_toTopOf="@+id/guideline1"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="@+id/guideline1"
/>
<ImageView
android:id="@+id/ivseconddiv"
android:layout_width="76dp"
android:layout_height="2dp"
android:background="@drawable/stroke_divider"
android:layerType="software"
app:layout_constraintBottom_toBottomOf="@+id/ivotp"
app:layout_constraintStart_toEndOf="@+id/ivotp"
app:layout_constraintTop_toTopOf="@+id/ivotp"
/>
<ImageView
android:id="@+id/ivfirstdiv"
android:layout_width="76dp"
android:layout_height="2dp"
android:layerType="software"
android:src="@drawable/stroke_divider"
app:layout_constraintBottom_toBottomOf="@+id/ivotp"
app:layout_constraintEnd_toStartOf="@+id/ivotp"
app:layout_constraintTop_toTopOf="@+id/ivotp"
/>
<ImageView
android:id="@+id/ivnumberfill"
android:layout_width="16dp"
android:layout_height="16dp"
app:layout_constraintBottom_toBottomOf="@+id/ivfirstdiv"
app:layout_constraintEnd_toStartOf="@+id/ivfirstdiv"
app:layout_constraintTop_toTopOf="@+id/ivfirstdiv"
app:srcCompat="@drawable/ic_otp_fill"
/>
<ImageView
android:id="@+id/ivprofile"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_toRightOf="@+id/ivseconddiv"
android:background="@drawable/otp_process_circle"
app:layout_constraintBottom_toBottomOf="@+id/ivseconddiv"
app:layout_constraintStart_toEndOf="@+id/ivseconddiv"
app:layout_constraintTop_toTopOf="@+id/ivseconddiv"
/>
<TextView
android:id="@+id/tvnumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ivnumberfill"
android:layout_marginTop="4dp"
android:text="Mobile Number"
android:textColor="?colorAccent"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="@id/ivnumberfill"
app:layout_constraintStart_toStartOf="@id/ivnumberfill"
app:layout_constraintTop_toBottomOf="@id/ivnumberfill"
/>
<TextView
android:id="@+id/tvotp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ivnumberfill"
android:layout_marginTop="8dp"
android:text="OTP"
android:textColor="#949595"
android:textSize="11sp"
app:layout_constraintEnd_toStartOf="@+id/ivseconddiv"
app:layout_constraintStart_toStartOf="@+id/ivotp"
app:layout_constraintTop_toBottomOf="@+id/ivotp"
/>
<TextView
android:id="@+id/tvprofile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ivnumberfill"
android:layout_marginTop="8dp"
android:text="Profile"
android:textColor="#949595"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="@+id/ivprofile"
app:layout_constraintStart_toStartOf="@+id/ivprofile"
app:layout_constraintTop_toBottomOf="@+id/ivprofile"
/>
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"
/>
<android.support.constraint.Guideline
android:id="@+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"
/>
</android.support.constraint.ConstraintLayout>

After building this UI I got to know importance and use of ConstraintLayout and Now I try to use ConstraintLayout everywhere possible.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Responses (1)

Write a response