Use ConstraintLayout to design your Android views

1. Before you begin

In this codelab, you'll learn how to use the Android Studio Layout Editor with ConstraintLayout—a new, flexible, and efficient layout available in the Android Support repository. The Layout Editor uses ConstraintLayout to determine the position of a UI element. A constraint represents a connection or alignment to another view, the parent layout, or an invisible guideline.

You will be working primarily with the Layout Editor for this codelab and will not directly be editing the XML or Java code. By the end of this codelab, you'll have enough experience with the Layout Editor in Android Studio to be able to build a complex layout such as the one shown below.

Header image, offset fab, and some buttons and text boxes using Constraint Layout.

Prerequisites

  • Some Android app development experience
  • Experience with Android Studio

What you'll do

  • Learn to automatically constrain UI elements to the layout.
  • How to place and resize elements in the layout.
  • How to add constraints in order to position and align elements to other elements.
  • How to adjust an element's layout dimensions and margins.
  • Learn to infer constraints for a layout automatically.
  • Use barriers to align elements that dynamically vary in size.
  • Use chains to position multiple elements.

What you'll need

2. Get the sample app

To download the sample app, you can either:

... or clone the GitHub repository from the command line by using the following command:

$ git clone https://github.com/android/codelab-constraint-layout.git

Frequently asked questions

3. Run the sample app

First, let's see what the finished sample app looks like. Follow these instructions to open the sample app in Android Studio.

  1. If you downloaded the constraint-layout-master zip file, unzip the file.
  2. Open the constraint-layout-master folder to see the constraint-layout-start folder. android_studio_folder.png
  3. Open the constraint-layout-start project in Android Studio.
  4. Click the execute.pngRun button, and either choose an emulator or connect your Android device, which must be capable of running Android Lollipop (the minimum SDK supported is 22). The constraint-layout screen should appear:

4cb17d80265290b4.png

To use ConstraintLayout, the appropriate support library must be included in the build.gradle (Module: app) file in your project. The constraint-layout dependency is provided as a separate support library that works on all Android versions back to Android 2.3 (Gingerbread).

The starter app already includes the dependency in build.gradle. Android Studio templates also include this dependency for new projects.

When creating a new app project, always open build.gradle and check that the most recent version of the dependency is included. Android Studio highlights any dependency that is not the most recent version. If the dependency is highlighted, hover your pointer over the statement, and Android Studio suggests a newer version. Replace x.x.x with the suggested version number.

dependencies {
  ...
  compile 'com.android.support.constraint:constraint-layout:x.x.x'
}

4. The Layout Editor

Android Studio provides the Layout Editor for building layouts fast. You can drag UI elements to a visual design and blueprint view, position the elements in the layout, add constraints, and set attributes. Let's take a look:

  1. Open activity_main_done.xml from the Project pane. This opens the Layout Editor.
  2. The Design state 9a7a3b4ae92bb32a.pngshould already be selected; if not, click the Design state in the top right of the editor window.

b19cc15d9925400f.png

  1. If there is no blueprint, click the Show Blueprint icon 2e7121c2997b0da8.png in the toolbar.

d0baa870aee9739.png

Your Layout Editor pane should look like the one shown below.

87ff159aae84f822.png

The above figure shows the Layout Editor's components:

  1. Toolbar
  2. Palette
  3. Design view
  4. Blueprint view
  5. Component Tree

Click the Device in Editor button in the toolbar (shown as 43f3c19edaa0eb9d.pngin the above figure) to select different devices and see what the layout looks like on different device screens.

To see the XML code of the layout, click the Text selection 2b390d4087475d28.png next to the Design button 9a7a3b4ae92bb32a.png. To see a split view of XML and the design surface, select the Split button 230c52f94df1ea2c.png . You can see the XML attributes for each element in the layout. For example, the following shows an EditText element with constraints in the design view, and XML constraint attributes for the same EditText element as shown by the Text tab.

EditText element in design view:

ab38d10ba69b6ec4.png

EditText element in XML showing only the constraint attributes:

<EditText
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        ...
        app:layout_editor_absoluteX="73dp"
        app:layout_editor_absoluteY="176dp"
        app:layout_constraintLeft_creator="1"
        app:layout_constraintTop_creator="1"
        app:layout_constraintRight_creator="1"
        app:layout_constraintLeft_toLeftOf="@+id/settings"
        tools:layout_constraintLeft_creator="1"
        app:layout_constraintTop_toBottomOf="@+id/title"
        android:layout_marginTop="8dp"
        ...
/>

For example, the app:layout_constraintLeft_toLeftOf attribute in the above XML code positions the element's left side to the left of the settings element.

5. 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 manually, as we show later, or automatically using the Autoconnect tool.

Autoconnect can create two or more constraints for a UI element to the parent layout. After you drag the element to the layout, it creates constraints based on the element's position.

  1. Open activity_main_autoconnect.xml from the Project pane. The Design tab should already be selected; if not, click it.
  2. Ensure that the Autoconnect tool, Screen Shot 2016-05-12 at 8.30.36 PM.png located in the toolbar, is enabled. It may be disabled by default.
  3. In the blueprint or the preview, click, then drag the ImageView towards the center of the layout until dotted guidelines appear.
  4. Release the mouse button when you see guidelines running from top to bottom and also from left to right. You see that blue zig-zag lines that represent constraints connect the top, left, bottom and right edges of the view to the edges of the parent view, centering the ImageView in the layout as shown in the animated figure below:

ba0a939e7a480e0f.gif

Constraints are automatically added to all four sides of the view because the view is close enough to the center for the Layout Editor to assume it should be centered in the layout.

In the blueprint or design views, notice these handles on the ImageView:

Screen Shot 2017-05-08 at 3.07.14 PM.png Resizing Handle: You can drag the square resizing handles to resize the element. While dragging, the handle changes to an angled corner.

a218f51d7a5b38e0.png Constraint Handle: Click a constraint handle, shown as a circle on each side of an element, and then drag to another constraint handle or parent boundary to create a constraint. The constraint is represented by the zigzag line.

To align the ImageView to the top, select the ImageView, hover over the bottom constraint handle until the tooltip appears, and then Command ( in MacOS) or Control (Ctrl in Windows) click the bottom constraint handle to delete it:

deea536cdff90a73.gif

The view is now attached to the top of the layout, because there is only one vertical constraint (at the top). The horizontal constraints still position the view in the center.

With Autoconnect enabled, you can drag any element (such as a button) to any part of a layout to generate constraints against the parent layout. To show how this works:

  1. Drag a Button from the Widgets section of the Palette to any position in the layout and release the Button.

e415623de9fc841e.png

b1383bf6ade3f775.png

  1. Select the Button in the layout, and drag it to the lower right corner as shown below—until both the side and bottom margin guidelines appear. When you see the guidelines in both directions, release the Button. The Button snaps to the guidelines automatically.

baeb06c83f816d46.gif

Autoconnect then generates the constraints against the parent layout. Two constraints are automatically added to position the button relative to the parent layout. Since you dragged the button to margin guidelines, the Layout Editor includes 16dp as right and bottom margins that match the default margin guidelines:

4d10b86c33524ff0.png

6. Add and resize UI elements

In this exercise you start a layout from scratch by adding and resizing an ImageView.

  1. Open activity_main_start.xml from the Project pane and click the Design tab.
  2. Turn off the Autoconnect tool (click it once to show 429619d48db0a640.png), so that constraints don't appear automatically when adding a UI element.

Add an ImageView to the layout

  1. Find the ImageView in the Images section in the Palette and drag it anywhere in the layout.

a2a5b835f00b286e.png

The Resources dialog appears. The constraint-layout-start sample already includes resources for the codelab.

  1. Choose the @drawable/singapore resource, and click OK.

7c53648af38d0026.png

The ImageView appears in the layout.

  1. Drag the element around the layout, and drag corners to resize the image. By resizing the image, the width and height are fixed to specific dimensions.

456127be480ef916.gif

You'll see indicators in the Component Tree pane. Click the indicator to see more information. The warnings and errors include:

  • Missing constraints, which you will add later in this section.
  • Missing contentDescription attribute for the ImageView.

8e9056f281962957.png

Content Description attributes are important for building accessible applications. You will use an already available resource @string/placeholder for the attribute.

Modify attributes

To add or change attribute values, use the Attributes pane that opens on the right side of the Layout Editor:

  1. Select the ImageView element if it is not already selected.
  2. Click the Attributes tab on the far right side of the toolbar:

5c44139f507702ac.png

The Attributes pane opens so that you can change the attributes of the selected UI element.

  1. Add @string/placeholder into the contentDescription attribute.
  2. In the Attributes pane, you can also see the other attributes for the ImageView. Choose centerCrop from the scaleType dropdown menu to change the scaleType attribute.

548b32e2dbd3ade.png

Add constraints to the parent layout

The following animated figure demonstrates how to perform these steps:

  1. To add a constraint to the left edge of the ImageView, click and hold the constraint handle and drag the line to the left edge of the parent layout.
  2. To add the right edge constraint for the ImageView, drag from the constraint handle to the right edge of the parent layout.
  3. To add the top constraint for the ImageView, drag from the constraint handle to the top of the parent layout.
  4. To add the bottom constraint for the ImageView, drag from the constraint handle to the bottom of the parent layout.

5907f705beb7e4a8.gif

The Layout Editor automatically includes an 8dp margin around the ImageView by default. The size of the margin is shown above the constraint line:

e9f27c27c85cdca1.png

You will work with margins in the next section.

7. The view inspector

In this exercise you continue with the layout from the previous exercise, in which you constrained an ImageView to all four sides of the layout. If it is not already open, open activity_main_start.xml from the Project pane and click the Design tab.

The Attributes pane shows the view inspector in a square block at the top, above the ImageView attributes for src and contentDescription. The view inspector shows the UI element's constraints and margins, and sliders for adjusting the position of the element along the horizontal and vertical axis.

5448fd017427183e.png

In the above figure:

  1. Use this button to close the Attributes pane.
  2. Margin values appear on all four sides. Change a margin by clicking the value and choosing a different value.
  3. Inner lines indicate the constrained width and length.
  4. Use sliders to change the horizontal and vertical constraint bias for elements with opposing constraints.

Position elements with constraint bias

In the previous exercise you constrained an ImageView to all four sides of the layout. As a result, the element is centered horizontally and vertically in the layout. The measure of space between the element and the layout's border is known as the constraint bias.

If the element is centered, its constraint bias is 50%, which means the element is halfway between the two borders. If the bias is changed to 30% for horizontal constraints, the element would be placed closer to the left border. If it is changed to 70%, the element would be placed closer to the right border. The same is true of vertical constraints: the bias controls how far the element is from the top and bottom borders.

After adding two opposing horizontal constraints—a left and a right constraint—a horizontal slider appears in the view inspector to adjust the bias of the element along the horizontal axis. If you add two opposing vertical constraints, a vertical slider appears to adjust the vertical bias.

Since the ImageView is positioned with both horizontal and vertical opposing constraints, use the horizontal and vertical sliders to adjust the bias, as shown in the following animated figure:

a734a5ea925c368d.gif

You can also click the orientation tool to change the orientation, and then adjust the positioning:

2651ce934f150530.gif

Change the element's layout width and height

The inner lines within the view inspector let you change the UI element's layout_width and layout_height values relative to constraints. Clicking an inner line cycles through the following options for vertical and horizontal constraints:

Screen Shot 2016-05-12 at 5.14.18 PM.png

Fixed: Specify the width/height of the element.

Screen Shot 2016-05-12 at 5.13.12 PM.png

Match Constraints: Allow the element to occupy all available space to satisfy the constraint. (Note that this is not the same as the match_parent value for width or height, which sets the element to occupy all available space of the parent view. You shouldn't use match_parent for any view in a ConstraintLayout.) In the XML file, the value 0dp appears in the layout_width or layout_height attribute for Match Constraints.

Screen Shot 2016-05-12 at 5.14.04 PM.png

Wrap Content: Expand the element as needed to fit its content.

Experiment with changing the layout_width and layout_height values. The following animated figure shows how to use the inner lines to change the element's layout_width values:

  • From Fixed to Match Constraints, which sets the ImageView to occupy all layout space according to its constraints
  • From Match Constraints to Wrap Content, which expands the ImageView to the layout borders in order to fit the entire picture.

32e2c6691d28aa4f.gif

To use the skills you've learned, resize the ImageView to 118dp in height, and constrain it to the top and sides with a margin of 0, as shown in the figure below.

Hint: You can enter 118dp directly into the layout_height attribute.

e0940fd208db6ac0.png

8. Create constraints between elements

In this exercise you will add two Button elements and add a constraint from one to the other to position them together. You will also add two TextView elements, constrain one to the other to position them together, and use a baseline constraint to align them vertically.

Add two Button elements to the layout

First, add two Button elements to the layout from the previous exercise:

  1. Open activity_main_start.xml if it is not already open, and click the Design tab.
  2. Drag a Button from the Palette to the lower right corner of the parent layout.
  3. Constrain the button to the right side and to the bottom of the parent layout.

3900464cd6ab431d.gif

Constrain one element to another

To create a constraint between UI elements within a layout, click on one element's constraint handle and drag it to the other element's constraint handle.

  1. Drag a second Button to any location in the layout.
  2. Drag a constraint from the right side of the second Button to the left side of the first, as shown in the following animated figure.

3cd9fb78bd76ed11.gif

  1. Drag another constraint from the second Button to the bottom of the layout, as shown in the following animated figure. The Layout Editor automatically adds an 8dp margin, and as a result, the Buttons are aligned vertically.

6e87b774a9b9e3c8.gif

  1. Use the Attributes pane to add the text for each Button. As you enter the character s into the text attribute field, a popup menu shows the string resources in the project so that you can select one.

cae388fb4b0021d8.png

You can also use the Attributes pane to assign IDs to elements. After selecting an element, such as the Upload Button, enter the ID into the ID field at the top of the Attributes pane:

d15779df7a2cf3f.png

Use a baseline constraint

By using a baseline constraint, you can vertically align elements that have text, such as a TextView, EditText, or Button, so that the text baselines are aligned. Use baseline constraints to align elements that use different text sizes. Baseline constraints are also useful for aligning the text baselines of elements of different sizes.

  1. Drag a TextView from the Palette to the layout. Assign the @string/camera string resource to its text attribute, and the cameraLabel ID to the ID field.

327e754de83a610b.png

  1. Drag a Plain Text element from the Palette to the layout (a Plain Text element is an EditText view). Assign the @string/camera_value string resource to its text attribute, and the cameraType ID to the ID field. Note that the Plain Text element uses a larger text size which makes it wider and taller than the TextView.
  2. Right click the TextView "Camera" element and select "Show baseline":

e8e40c8aec60a24.png

  1. Then click and drag from the TextView's baseline, which is blinking in green, to the baseline of the Plain Text element, as shown in the following animated figure:

f51a4d7b125cf7e1.gif

  1. You can now add a constraint to bring the two elements closer to each other, and move them in the layout to another location—the elements move together and stay aligned:

3855471c8891cc3c.gif

  1. You can also use a baseline constraint to align the Button elements. Select the Discard button right click on it and choose "Show baseline", as shown in the following animated figure:

b863e1277b9acf21.gif

  1. After adding the baseline constraint, the bottom constraint of the Discard button is automatically removed. You can now change the margin for the Upload button, and the Discard button will still be aligned with it. Select the Upload button, and change the right and bottom margins to 16dp in the Attributes pane, as shown in the animated figure below.

e8ed7523eff702a8.gif

9. Pack elements and infer constraints

In this exercise you learn how to expand an element horizontally and vertically using the Pack 951760555db8c61a.png tool, and how to use the Infer Constraints f766e5b43820a88b.png tool. Both tools are in the toolbar at the top of the Layout Editor.

For this exercise, open the activity_main_inference.xml layout and click the Design tab. Note the following:

  • The layout includes the header ImageView for the image of Singapore, the favorite ImageView for a star, and the Upload and Discard buttons.
  • The favorite image is constrained to have a vertical bias at 19%. To see the vertical bias, select the element and look at the view inspector's vertical slider (shown in the figure below).
  • The bottom handle of header is constrained to the bottom handle of favorite, with a margin of 16dp.
  • Text elements are provided but not constrained:
  • The textView element showing "Camera" is a label that uses the string resource @string/camera.
  • The textView2 element showing "Settings" is a label that uses the string resource @string/settings.
  • The cameraEdit element showing "Leica M Typ 240" is an EditText that uses the string resource @string/camera_value.
  • The settingsEdit element showing "f/4 16s ISO 200" is an EditText that uses the string resource @string/settings_value.

678913b15b731834.png

The Pack tool

In this exercise, you'll add a TextView for the description of the image, and expand it to fill available space.

  1. Drag a new TextView from the Palette and place it below the other text elements.
  2. With the new TextView selected, click the Expand Horizontally ec852f154eab7e5d.pngtool in the Pack tool to expand the view horizontally to fill available space, as shown in the following figure:

a75f3d1bdc7745b1.png

The result of expanding the text element horizontally:

8d48d4474954c7b2.png

  1. With the TextView selected, click the Expand Vertically 233b24b3c9abdab.pngtool to expand vertically to fill available vertical space.

The result of expanding the text element vertically:

b1af6d7854e1f5d2.png

The TextView now fills the available space in the layout.

  1. With the TextView selected, set its text to @string/singapore_description in the Attributes pane.

The Infer Constraints tool

The Infer Constraints tool infers, or figures out, the constraints you need to match a rough layout of elements. It works by taking into account the positions and sizes of the elements. Drag elements to the layout in the positions you want them, and use the Infer Constraints tool to automatically create the constraint connections.

Click the Infer Constraints f766e5b43820a88b.pngtool. The Layout Editor adds constraints to all of the unconstrained elements in the layout. The resulting layout should look like the following:

215b29796af5fafa.png

10. Use ratios to size elements

You can quickly resize elements by aspect ratio if at least one of the element's dimensions is set to match constraints.

For this exercise, open activity_main_ratio.xml and click the Design tab. Drag an ImageView from the Palette to the layout, and select singapore in the Resources dialog.

Select the ImageView and add constraints and dimensions, as shown in the figure below with the following callouts:

  1. Bottom constraint connected to the bottom of the layout with a 0 margin.
  2. Side constraint connected to the left side of the layout with a 0 margin.
  3. Top constraint connected to the top of the layout with a 0 margin.
  4. Side constraint connected to the right side of the layout with a 0 margin.
  5. The layout_width attribute set to wrap_content, and the layout_height to match_constraint.

b83d2c739daa9105.png

As soon as you constrain one dimension to be match_constraint, the Toggle Aspect Ratio Constraint option appears in the inspector view in the top left corner of the square.

Click the Toggle Aspect Ratio Constraint option. The ratio entry box appears below the bottom right corner of the square:

e5ef1da97645a41.png

To enable aspect ratio constraints and set your ImageView to have a 16:9 aspect ratio, enter 16:9 in the ratio field:

f188752d2c8c8bea.gif

You can see the entire action and result in the following animated figure:

52b2eb50c3aaf9ca.gif

By using ratios you can ensure your designs stay perfect while allowing images to be resized on different device screens.

11. Use barriers to align elements that dynamically vary in size

Barriers allow you to specify a constraint based on multiple UI elements. You'll want to use barriers any time that multiple elements could dynamically change their size based on user input or language.

For example, if the user chooses German, the sample app shows the text in German. German words may be longer, and the text may overlap the next element. To see an example, open activity_main_barriers.xml and click the Design tab, and then choose German from the Language menu:

7134049c6d584a05.png

The following animated figure shows how the text elements may overlap when switching from English to German (and back to English):

49f793d8d106d92a.png

This exercise walks you through adding a barrier to this layout so that the label, which can vary in size depending on the language translation, doesn't overlap the entry field.

  1. Choose German from the Language menu if it has not already been chosen, so that the app's layout appears in German.
  2. Right click on ConstraintLayout in the blueprint or the Component Tree. You will see the Add Vertical barrier and Add Horizontal barrier options.

355864f91e27c7d5.png

  1. To create a vertical line for the two TextView elements, select Add Vertical barrier to add a barrier. You want to create a vertical line for the two TextViews, as shown below with callout 1:

a3ba82581cf2a59d.png

  1. Open Component Tree to view your new barrier. You won't find the barrier in Design or Blueprint view yet because it's flush with the start of the container. You can find Component Tree in the bottom left.
  1. Select both cameraLabel and settingsLabel in your Component Tree. Drag both onto your barrier in the Component Tree. When you do this you're specifying that the barrier should float based on the position of both labels.

9006e9ab825c777e.gif

  1. Select barrier in the Component Tree and open the Attributes pane to set the attribute barrierDirection to end. The barrierDirection is an attribute that controls how the barrier is positioned relative to the referenced views.

With the vertical barrier in place, you can constrain an element to the right side of the barrier:

  1. Delete the constraint from the left side of cameraType to the right side of cameraLabel ("Kamera"), as shown in the following animation:

91dc9cb9fbcceba1.gif

  1. Drag a constraint from the left side of cameraType to the barrier:

ca458bff73338979.gif

  1. You can now use the Language menu to switch from English to German and back, and see how the barrier aligns the elements so that they don't overlap.

a58fb6aefb9ce1fd.png

A constraint to a barrier is just like a constraint to another element. However, users don't see barriers, and barriers don't add a level to the app's view hierarchy, which means they don't affect performance.

12. Use chains to position multiple elements

You've already learned how to center a single UI element. In this exercise you will learn how to center multiple elements at once using a chain. A chain is a group of elements that are linked to each other with bi-directional position constraints.

The following shows two elements that are constrained to each other, creating a horizontal chain.

56744e8112302ff7.png

When you create a chain, you can position all of the elements as a group, and center all of your chained elements as if they were a single element.

For this exercise, open activity_main_chains.xml and click the Design tab.

  1. Select both EditText elements.
  2. Right-click on the selected elements and choose Center Vertically from the menu. This will automatically create a chain as well as generate constraints to the top and bottom of the parent layout.

b9c5d9574977b8f2.png

  1. Add a margin between the EditText elements by selecting cameraType and giving it a bottom margin of 8dp.
  2. Select either EditText element, and drag the vertical bias slider to 20. This will shift both elements towards the top without specifying a fixed constraint.

46b439247ee926fb.gif

  1. Click the e773eaeb32767458.png button and choose Switch to Landscape. You will see the elements maintain the 20% bias as the container changes size.

This exercise demonstrated the basics of using chains. To learn more about chains, you can read the Android guide on controlling linear groups with a chain.

13. Congratulations!

You learned how to create layouts with the ConstraintLayout viewgroup.

Learn more

To learn more about ConstraintLayout, see Build a Responsive UI with ConstraintLayout. For an overview of the Layout Editor, see Build a UI with Layout Editor. Thank you for giving ConstraintLayout a try, and we hoped you enjoyed this codelab!