Skip to content
Android

Android development tips: Constraint Layout helpers II. part

Peter Šuly14 Apr 2021
Android development tips: Constraint Layout helpers II. part

I brought you the second part of an article about Constraint Layout Helpers, which are type of ViewGroup, which allows you to create complex layouts. Full power of Constraint Layouts comes from his helpers, so i've prepared the article about them.

In the first part of the introduction to Constraint Layout Helpers, I introduced Group, Guidline, Layer and Barrier. If you haven't seen them yet, don't forget to visit the first part!

Placeholder

Placeholder is helper which can help to position another views (that's where it's name comes from - it's "holding place" for view). When you call setContentId() method on placeholder object somewhere in your code, placeholder objects become the content view. If content view exists on the screen already, it will be treated as gone on its original location after setContentId() call.

E.g. when some of the upper circles is clicked, placeholder.setContentId() is called, placeholder becomes the clicked view (clicked view moves to placeholder's position, inherits placeholder's constraints).

 

val onClickListener = View.OnClickListener { view -> TransitionManager.beginDelayedTransition(content) //For animation effect placeholder.setContentId(view.id) //Set view to placeholder } image1.setOnClickListener(onClickListener) image2.setOnClickListener(onClickListener) image3.setOnClickListener(onClickListener)<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:id="@+id/content" android:paddingTop="16dp"> <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_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_constraintStart_toEndOf="@id/image1" app:layout_constraintEnd_toStartOf="@id/image3"/> <ImageView android:id="@+id/image3" android:layout_width="64dp" android:layout_height="64dp" android:src="@drawable/background_badge_black" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toEndOf="@id/image2" app:layout_constraintEnd_toEndOf="parent"/> <androidx.constraintlayout.widget.Placeholder android:id="@+id/placeholder" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginBottom="16dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>

Don't miss my #goodroidtips I. or II. ,articles about useful tips and tricks for Android developers.

Flow

Similar to Group, Flow takes views ids into constraint_referenced_ids attribute and automatically creates Chain behavior between them. Chain behavior (way how views overflow the Flow) is determined by wrapMode attribute of Flow.

//Default behavior of Flow, just creates chain between referenced views //If views do not fit into Flow, they will overflow the Flow app:flow_wrapMode="none" OR //If views do not fit into Flow, they jump on another line and take place evenly app:flow_wrapMode="chain" OR //If views do not fit into Flow, they jump on another line and align to create rows and columns app:flow_wrapMode="aligned"

As we said, Flow automatically creates chain between it's elements. Chain style can be configured by flow_horizontalStyle or flow_verticalStyle attribute based on Flow's orientation. Behavior of chain style is basically the same as for chains.

For horizontal Flow app:flow_horizontalStyle="spread" //Default OR app:flow_horizontalStyle="packed" OR app:flow_horizontalStyle="spread_inside"


 

First and last chain in the Flow can have different style attributes  as others e.g. for the first chain we define flow_firstHorizontalStyle="spread_inside" for the last chain we define flow_lastHorizontalStyle="packed". All the others chains in the middle took default flow_horizontalStyle="spread" because we did not defined anything.

<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.helper.widget.Flow android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" app:flow_wrapMode="chain" app:flow_maxElementsWrap="2" app:flow_firstHorizontalStyle="spread_inside" app:flow_lastHorizontalStyle="packed" app:constraint_referenced_ids="circle1, ..., circle9"/> //Include 9 circles <include android:id="@+id/circle1" layout="@layout/circle"/> </androidx.constraintlayout.widget.ConstraintLayout>

 

Flow can be customized by many other attributes e.g.

//Orientation of Flow, can be vertical or horizontal android:orientation="vertical" //Maximum number of elements in one row or column app:flow_maxElementsWrap="3" //Vertical or horizontal gap between referenced views app:flow_horizontalGap="20dp" app:flow_verticalGap="20dp"

Bonus

Circular positioning

Circular positioning attributes allows you to constraint view to another view at specified angle and distance. Important attributes when we want to circularly position views are

app:layout_constraintCircle="@id/baseImage" //Constrained base view app:layout_constraintCircleRadius="90dp" //Radius of the circle app:layout_constraintCircleAngle="45" //Degree of the circle on which we display the view

E.g. positioning image1, image2 and image 3 around baseImage in 0, 45 and 90 degree.

<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="32dp" android:layout_height="32dp" android:src="@drawable/background_badge_green" app:layout_constraintCircle="@id/baseImage" app:layout_constraintCircleRadius="90dp" app:layout_constraintCircleAngle="0"/> <ImageView android:id="@+id/image2" android:layout_width="32dp" android:layout_height="32dp" android:src="@drawable/background_badge_green" app:layout_constraintCircle="@id/baseImage" app:layout_constraintCircleRadius="90dp" app:layout_constraintCircleAngle="45"/> <ImageView android:id="@+id/image3" android:layout_width="32dp" android:layout_height="32dp" android:src="@drawable/background_badge_green" app:layout_constraintCircle="@id/baseImage" app:layout_constraintCircleRadius="90dp" app:layout_constraintCircleAngle="90"/> <ImageView android:id="@+id/baseImage" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginBottom="16dp" android:layout_marginStart="16dp" android:src="@drawable/background_badge_black" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>

Resources: https://developer.android.com/reference

Reach out anytime

Ready to start a project?
Let's build together.

Schedule a call or send an email.

Contact us

Not sure where to start? Download our product brief template.