Constraint Layout is a ViewGroup which allows you to create large and complex layouts with a flat view hierarchy, and also allows you to position and size widgets in a very flexible way.It was created to help reduce the nesting of layout or views and also improve the performance of layout files.
ConstraintLayout similar to RelativeLayout in that all views are laid out according to relationships between sibling views and the parent layout, but it’s more flexible than RelativeLayout and easier to use with Android Studio’s Layout Editor.It was released at Google I/O 2016. Since it came into existence Android Studio, it has become a widely used viewgroup and supports Android 2.3 or higher.
Note: ConstraintLayout is available as a support library that you can use on Android systems starting with API level 9 (Gingerbread). After releasing of Android JetPack, it is shifted to AndroidX library.The support library has been superseded by AndroidX which is part of Jetpack.
Android Studio Layout Editor:
ConstraintLayout is available directly from the Layout Editor’s visual tools, because the layout API and the Layout Editor were specially built for each other. So you can build your layout with ConstraintLayout entirely by drag-and-dropping instead of editing the XML.
Layout Editor provide the facility for quickly building layouts. It lets you drag UI elements to a visual design and blueprint view, position the elements in the layout, add constraints, and set attributes.
Layout Editor’s components:
- Design view
- Blueprint view
- Component Tree
To define a view’s position in ConstraintLayout, you must add at least one horizontal and one vertical constraint for the view. Each constraint represents a connection or alignment to another view, the parent layout, or an invisible guideline. Each constraint defines the view’s position along either the vertical or horizontal axis, so each view must have a minimum of one constraint for each axis, but often more are necessary.
Convert a layout:
To convert an existing layout to a constraint layout, follow these steps:
- Open your layout in Android Studio and click the Design tab at the bottom of the editor window.
- In the Component Tree window, right-click the layout and click Convert layout to Constraint layout.
Next, you should get a pop-up dialog with some options:Accept the defaults after reading what they do and click on OK to dismiss the dialog and convert the layout. Android Studio will then attempt to remove all the nested layouts and convert your layout to ConstraintLayout.
Create constraints automatically:
The Layout Editor uses constraints to determine the position of a UI element within the layout. A constraint represents a connection or alignment to another view, the parent layout, or an invisible guideline.You can create the constraints automatically using the Auto Connect tool.The Auto connect tool is located in the toolbar. It is enabled by default. Constraints are automatically added to all four sides of the view.
Relative positioning is one of the basic building blocks of creating layouts in ConstraintLayout. Those constraints allow you to position a given widget relative to another one. You can constrain a widget on the horizontal and vertical axis:
- Horizontal Axis: left, right, start and end sides
- Vertical Axis: top, bottom sides and text baseline
The general concept is to constrain a given side of a widget to another side of any other widget.
Example : <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/button1" />
List of available constraints:
Text Baseline to Text Baseline Alignment:
To create a baseline constraint, right-click the text view you want to constrain and then click show baseline. Then click on the text baseline and drag the line to another baseline.
Constraint Relative to Guideline:
So far, you’ve constrained UI elements to their parent containers and to each other. Another option you have is to add invisible guidelines to the layout and constrain UI elements to those guidelines
You can add a vertical or horizontal guideline to which you can constrain views, and the guideline will be invisible to app users. You can position the guideline within the layout based on either dp units or percent, relative to the layout’s edge.
If two sides of a view are constrained on the same axis, the widget will be positioned center between the two constraints. In this case, layout editor shows constraint line differently as shown below.Position of a view between the two constraints on the same axis can be controlled by a property called bias.By default bias is 50%, which is why view is centered between two constraints. You can change bias in the properties window or in the editor by dragging the view.
The two bias constraint xml attributes are:
Example : <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.3" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" 4 />
The dimension of the widgets can be specified by setting the android:layout_width and android:layout_height attributes in 3 different ways:
- Using a specific dimension (either a literal value such as 100dp or a Dimension reference)
- Using WRAP_CONTENT, which will ask the widget to compute its own size
- Using 0dp, which is the equivalent of “MATCH_CONSTRAINT”
The first two works in a similar way as other layouts. The last one will resize the widget in such a way as matching the constraints that are set ( (a) is wrap_content, (b) is 0dp). If margins are set, they will be taken margin in the computation as we set.
Setting View Size as Ratio:
You can also define one dimension of a widget as a ratio of the other one. In order to do that, you need to have at least one constrained dimension be set to 0dp (MATCH_CONSTRAINT), and set the attribute layout_constraintDimensionRatio to a given ratio. Example width of a view is set to match constraint (0dp) and you want height to be 3:2, then setting would be app:layout_constraintDimensionRatio=”H,3:2″.
You can also use ratio if both dimensions are set to MATCH_CONSTRAINT (0dp). In this case the system sets the largest dimensions that satisfies all constraints and maintains the aspect ratio specified. To constrain one specific side based on the dimensions of another, you can pre append W,” or H, to constrain the width or height respectively. For example, If one dimension is constrained by two targets (e.g. width is 0dp and centered on parents) you can indicate which side should be constrained, by adding the letter W (for constraining the width) or H (for constraining the height) in front of the ratio, separated by a comma:
<Button android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="52dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="H,3:2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" />
Chains provide group behavior in a single axis (horizontally or vertically). The other axis can be constrained independently.A set of widgets are considered a chain if they are linked together via a bi-directional connection (showing a minimal chain, with two widgets).
Chains are controlled by attributes set on the first element of the chain (the “head” of the chain).The head is the left-most widget for horizontal chains, and the top-most widget for vertical chains.If margins are specified on connections, they will be taken in account. In the case of spread chains, margins will be deducted from the allocated space.
Chain styles are following:
- CHAIN_SPREAD — the elements will be spread out (default style)
- Weighted chain — in CHAIN_SPREAD mode, if some widgets are set to MATCH_CONSTRAINT, they will split the available space
- CHAIN_SPREAD_INSIDE — similar, but the endpoints of the chain will not be spread out
- CHAIN_PACKED — the elements of the chain will be packed together. The horizontal or vertical bias attribute of the child will then affect the positioning of the packed elements
Dealing with View.GONE:
When dealing with View.GONE visibility of Views in ConstraintLayout, you have more control compared to RelativeLayout. First of all, any View that is set to GONE shrinks to zero size in both dimensions, but still participates in calculating constraints. Any margins set on the constraints on this View are also set to zero.
In many cases, a set of views connected by constraints such as in the example below will just work when setting a view to GONE.
There is also a way to specify a different margin for a constraint in case a view to which the constraint is attached gets removed via GONE.
You can also indicate a different margin value to be used using the following attributes: