Notes on the Classic Containers

While ConstraintLayout is the recommended solution for Jetpack-based Android app development, it is not the only option. And since ConstraintLayout is relatively new, there is a lot of existing code that does not use it.

Four container classes were the dominant options starting with Android 1.0 and can still be used today: LinearLayout, RelativeLayout, TableLayout, and FrameLayout.

LinearLayout

LinearLayout represents Android’s approach to a box model — widgets or child containers are lined up in a column or row, one after the next. Since many other GUI toolkits use this sort of an approach, a lot of developers used LinearLayout extensively. Plus, it is very easy to use: other than an android:orientation attribute to indicate if it should be a row (horizontal) or column (vertical), nothing else is required.

And, for fairly simple scenarios, there is nothing wrong with using LinearLayout.

However, LinearLayout was designed around simple usage and simple implementation, not performance. Having lots of nested LinearLayout containers can slow things down. And for a complex form, you would need lots of LinearLayout containers. Even something as simple as ConstraintForm would take three LinearLayout instances:

RelativeLayout

On the surface, RelativeLayout looks a lot like ConstraintLayout. RelativeLayout, as the name suggests, lays out widgets based upon their relationship to other widgets in the container and the parent container. You can place Widget X below and to the left of Widget Y, or have Widget Z’s bottom edge align with the bottom of the container, and so on. And it does so via special attributes on the children, saying what they are anchored to.

All of that sounds like ConstraintLayout.

However, RelativeLayout was not created with performance or drag-and-drop GUI builders in mind. ConstraintLayout has a superset of RelativeLayout features, and RelativeLayout has its own set of attributes similar to, but distinct from, those in ConstraintLayout. There is little reason to use RelativeLayout today.

TableLayout

If you like HTML tables, you will like Android’s TableLayout. It allows you to position your widgets in a grid to your specifications. You control the number of rows and columns, which columns might shrink or stretch to accommodate their contents, and so on.

TableLayout works in conjunction with TableRow. TableLayout controls the overall behavior of the container, with the widgets themselves poured into one or more TableRow containers, one per row in the grid. Using a TableLayout with TableRow works a lot like using an HTML <table> with <tr> elements.

When Android started out, HTML tables were very popular, not only for tabular data but for general page layout. CSS had only caught on in recent years, so lots of Web developers were used to using HTML tables to try to position things on the screen in the desired locations. Having a TableLayout that mimicked HTML tables was a logical move, to help ease the transition for those early Web designers.

With Barrier, you can set up a ConstraintLayout that can handle table structures, with rows and columns, where the columns can vary in width based on contents. However, it is likely that there will be some scenarios that would be very difficult to implement with ConstraintLayout that TableLayout could handle easily. Overall, though, ConstraintLayout is much more powerful than is TableLayout. Plus, TableLayout suffers from the same performance problems of LinearLayout, with lots of nested containers.

So, in general, if you see a grid sort of structure, try using a ConstraintLayout, and consider falling back to TableLayout only if needed.

FrameLayout

Android has a FrameLayout class. Like ConstraintLayout, LinearLayout, RelativeLayout, and TableLayout, FrameLayout exists to size and position its children. However, FrameLayout has a very simple pair of layout rules:

  1. All children go in the upper-start corner (e.g., upper-left for LTR languages), unless android:gravity indicates to position the children elsewhere
  2. Children can overlap on the Z axis (which ConstraintLayout and RelativeLayout also support)

The result is that all the widgets are stacked one on top of another.

This may seem useless.

Primarily, FrameLayout is used in places where we want to reserve space for something, but we do not know what the “something” is at compile time. The decision of what the “something” is will be made at runtime, where we will use Java/Kotlin code to put something in the FrameLayout. We will see this pattern used with fragments, later in the book.

Occasionally, FrameLayout is literally used for “framing”, where we want some sort of a border around a child. In this case, the background of the FrameLayout (e.g., android:background) defines what the frame should look like.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.