The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.


Introducing ConstraintLayout

In 2016, Google released a new container class, ConstraintLayout, that it hopes will become popular among Android developers as an alternative to LinearLayout and RelativeLayout. Certainly, Google is going to “pull out all the stops” to convince developers to use ConstraintLayout, such as having it be used in many of the activity templates employed by Android Studio’s new-activity wizard.

ConstraintLayout is useful, but it is not required for Android app development, any more than LinearLayout and RelativeLayout are. And, since ConstraintLayout is a library, you will need to take some additional steps to add it to your project, and it adds ~100KB to the size of your Android app. Whether it is worth that extra space and time is for you to decide.

NOTE: At the present time, ConstraintLayout is still in an beta state. It may change a fair bit before it gets released in final form. While the graphical layout editor in Android Studio 2.2 is supposed to be release-quality, it behaves as though it is beta-quality. Future editions of this book will update this chapter to reflect newer versions of ConstraintLayout and hoped-for stability in the graphical layout editor.

Why Another Container?

LinearLayout, RelativeLayout, and (to a lesser extent) TableLayout have served as the backbone of most Android apps. Previous attempts to provide a new foundation container class — such as GridLayout – have not proven to be successful.

So, why did Google bother creating ConstraintLayout?

Drag-and-Drop GUI Builders

Google would like everyone to use Android Studio, and in particular for everyone to use Android Studio’s drag-and-drop GUI builder.

How well a drag-and-drop GUI builder works depends a lot on how the rules for laying out a UI get defined. With drag-and-drop gestures, the developer is only providing you with X/Y coordinates of a widget, based on where the developer releases the mouse button and completes the drop. It is up to the GUI builder to determine what that really means in terms of layout rules.

With LinearLayout, adding a widget is fairly easy:

TableLayout is a bit more involved but still not that bad, as we have decades of experience of working with spreadsheets to know about inserting rows and columns into a grid-like structure.

RelativeLayout, though, was difficult for a GUI builder to handle. Often, the Android Studio GUI builder (and its predecessor in Eclipse) would misinterpret the developers wishes. Sometimes, the rules the developer wanted to express were simply unavailable through pure drag-and-drop operations. As a result, developers had to dive into the XML to get anything done. Being able to read layout XML is important – otherwise, books like this would be unusable. However, forcing developers to write the XML defeated the purpose of the GUI builder.

ConstraintLayout was created with GUI building in mind, to make it a bit easier to infer the right rules based upon where the developer happens to drop a widget.

Performance

RelativeLayout, LinearLayout with android:layout_weight, and TableLayout with android:stretchColumns/android:shrinkColumns, all require two passes over their children to determine final sizes and positions. For example, with a weighted LinearLayout, you need to make one pass to calculate the directly-expressed sizes (e.g., android:layout_height), followed by a second pass to allocate the remaining space according to the weight.

This gets exacerbated by the fact that changing the details of a widget often cause the sizes to have to be recomputed. Suppose that you change the text in a TextView with android:layout_width="wrap_content". Changing the text changes the horizontal space taken up by that text. So, the TextView winds up telling its container “hey, please recompute the sizes and positions”, as the larger TextView might now cause shifts in other children of the container. Depending on how the container itself is sized, it might need to tell its container to recompute the sizes and positions.

Cascading upward to have parents re-size/re-position their children gets very expensive for deep hierarchies, where we have containers holding containers holding containers holding containers and so on. One change in text of a TextView might cause that whole hierarchy to go through re-size/re-position work.

All else being equal:

ConstraintLayout is being designed with performance in mind, trying to eliminate as many two-pass scenarios as possible and by trying to eliminate the need for deeply-nested view hierarchies. Right now, in the beta releases, ConstraintLayout performance is not that great. However, it is a focus area and should improve over time.

Comparing with the Classics

Stylistically, ConstraintLayout most closely resembles RelativeLayout. As with RelativeLayout, you can anchor widgets to other widgets inside the ConstraintLayout or to the boundaries of the ConstraintLayout itself.

Many structures that can be implemented using LinearLayout but not RelativeLayout — such as allocating widget sizes based on weights – can be handled by ConstraintLayout. ConstraintLayout is designed to handle such conditional sizing without requiring two passes through its children to determine those sizes.

However, TableLayout remains distinct. ConstraintLayout does not have the notion of columns, let alone sizing those columns based upon their contents and layout rules.

Getting ConstraintLayout

The preview of this section was abducted by space aliens.

Using Widgets and Containers from Libraries

The preview of this section was lost in the sofa cushions.

Using a ConstraintLayout

The preview of this section was traded for a bag of magic beans.

Converting Existing Layouts

The preview of this section was fed to a gremlin, after midnight.

Visit the Trails!

The preview of this section was whisked away by a shark-infested tornado.