Three key lessons when migrating to ConstraintLayout

Lightning Talk @Droidcon London 2017

INTRODUCTION

The ConstraintLayout was launched at Google I/O in 2016 and introduced a number of new layout concepts including a flat view hierarchy. Compare to legacy layouts, the ConstraintLayout has shown some key benefits such as ease of use, flexibility and improved layout performance.

Despite this, many applications have not yet migrated from legacy layouts to ConstraintLayout. In this article I will demonstrate the step-by-step process of migrating a number of legacy layouts toConstraintLayout, highlighting some benefits and key lessons to take away.

ASSUMPTIONS

When migrating to the ConstraintLayout, I am making the following assumptions:

  • Visual standpoint: From a visual standpoint — the migrated layout should be similar to the original designs so that differences are unrecognisable by the end user and ideally I want them to match pixel by pixel.
  • View properties: The information about each view should remain the same throughout the transition.
  • Benefits: I expect to see some benefits, including reduced nesting.

THE LAYOUTS

For this project, I built a simple recipe app using five different layouts as specified below which I will migrate to ConstraintLayouts. This project is also available on GitHub.

STEP-BY-STEP PROCESS

SET-UP (Source: Google)

Set-up: The step-by-step documentation can be found here.

STEP 1/3: CONVERT TO CONSTRAINTLAYOUT

The emulator toolbar.

1a) Save a screenshot of the current layout using the emulator (click the camera button).

1b) Copy the contents of the XML file and paste it in a new layout file.

1c) In the new file, navigate to the design tab and under Component Tree right click on the layout (in this case RelativeLayout) and select “Convert RelativeLayout to ConstraintLayout”.

STEP 2/3: REPOSITION AND REFACTOR

2a) Take a screenshot of the new converted layout and compare it to the old layout (I used an online image comparison tool which can be found here).

The differences between the images (highlighted in red) after converting a RelativeLayout to ConstraintLayout

2b) Reposition: Once I converted the layouts, I repositioned the views until there were minor or no differences between them.

The differences between the images (highlighted in red) after repositioning the views

2c) Refactor: There are a number of XML attributes that will be generated when converting to ConstraintLayout, which can be helpful when repositioning the views. See tips on how to use them below:

STEP 3/3: COMPILE

Run the UI tests to make sure they are passing and ensure the new layout meets the design requirements.

LESSONS LEARNED

Overall, the migration process was smoother and less time-consuming than I expected. However, for LinearLayouts I found it difficult to get the exact same UI output pixel by pixel despite using chains (see below), but I got close enough. Below are some recommendations to speed up the migration process:

1. Flatten hierarchies before converting: Flattening RelativeLayout hierarchies that have a lot of nesting (2+ layers) proved tricky. I found that flattening hierarchies to max two levels of nesting before converting significantly improved the accuracy of the conversion result.

Tip: Don’t spend too much time repositioning the views after flattening the hierarchy. They will probably need to be repositioned once migrated so overall it will be a lot less time-consuming.

2. Understand the RelativeLayout translations: The RelativeLayout directly translates into the ConstraintLayout which eases the migrating process. I put together the table below of translations I found the most useful:

RelativeLayout to ConstraintLayout translations

Tip: Don’t forget that margins will be ignored in ConstraintLayout unless constrained, see example below:

3. Use chains to reposition LinearLayouts: Converting LinearLayouts meant I had to translate group of views and to do this I used chains. Chains provide group-like behaviour in a single axis (horizontally or vertically) — click here for more information. To create a chain of views, select them all, right-click one of the views, and then select either Center Horizontally or Center Vertically.

A chain in ConstraintLayout

Tip: To position the group, insert the below constraints in the chain’s head and update the values to reflect the type of chain and use horizontal/vertical bias to position the chain of views. Below is the code I used to position what was previously a horizontally centred LinearLayout:

app:layout_constraintHorizontal_chainStyle=”packed”
app:layout_constraintHorizontal_bias=”0.5"

RESULTS

Below are the final results, showing the difference between each layout and the newConstraintLayout. Despite not being able to reposition the LinearLayout to be exactly the same, it satisfied the UI requirements and I can now enjoy all the benefits of the ConstraintLayout!

Performance: I managed to flatten all the layout hierarchies. With regards to rendering times, it was difficult to draw conclusions due to the small size of the application and the complexity of testing layout performance.

Using the Hierarchy Viewer in the Android Device Monitor

Flexibility: After having migrated to ConstraintLayout, it became much easier to make amendments to the current layout, add new views and adjust current ones — this is especially true for complex layouts.

Ease of use: The Layout Editor is a great tool for repositioning views and I was surprised how quickly it became a clear preference over XML. Some of the features I used frequently include constraints, constraint bias, dimensions and baselineConstraint.

Conclusion

To summarise, the process of migrating from legacy layouts toConstraintLayout was smoother and more accurate than I expected and I would highly recommend using the auto converter tool. Even though it took some time getting my head around, the conversion process became quicker and more accurate as I became more familiar with the tools.

From a visual standpoint, the results satisfied the UI requirements and I was pleased to find out that all view properties remained the same during the conversion process. Overall, I highly recommend that you explore migrating to ConstraintLayout, especially if you have very nested hierarchies. As a next step, I would like to explore the effect on layout performance in more detail!

I hope you enjoyed this article and I would really appreciate your feedback! Feel free to ask any questions on here or on Twitter!

Thank you for reading,
Connie