At Google IO 2016 Google announced a new Android layout named ConstraintLayout. Despite the initial release being labelled as an Alpha release, it is actually pretty stable (with a few caveats). In this series of articles we’ll take a look at this new layout-kid on the block and try and get some insights in how best to use it.
Before we begin it is worth making some distinctions: ConstraintLayout is completely separate from the new layout editor. The new layout editor is not just designed to work with ConstraintLayout, it also works well with other layout types as well. Moreover the new layout editor is actually more than just a layout editor – it also allows the visual editing of menu resources as well as layouts so I’ll actually refer to it as the visual editor rather than the layout editor. There have been previous attempts at providing visual layout editing which, whilst well intentioned, have been somewhat lacking in their implementation – they don’t play nicely with custom Views, for example. It was these lessons learned from these previous attempts at visual layout editors that the new editor has been re-written from the ground up – and it shows – it is already much more capable of handling custom Views provided that you keep the constructors pretty clean and make full use of
View#isInEditMode() to ensure that it doesn’t try to do too much when it is being used inside a visual editor.
So although ConstraintLayout is distinct from the editor, the two do go rather hand-in-hand and ConstraintLayout has been designed to be crafted through the visual editor rather than hand-crafted XML. I spoke to a couple of Googlers who’d been playing with ConstraintLayout and both stated that they wouldn’t even consider hand-crafting XML simply because the visual editor was so good. Some initial concerns were voiced by developers about whether we’d actually be able to see the XML, but any concerns were short-lived as soon as you start playing with it because the visual editor supports the established pattern of bottom tabs which enable switching between Text (XML) and Design (visual editor) views. That said, the ConstraintLayout XML is quite voluminous and not the easiest to understand as a result.
Having discussed ConstraintLayout with a number of Android developers at IO there was a general feeling that ConstraintLayout was overall a good thing, but some people were expressing concerns about whether ConstraintLayout would play nicely with CoordinatorLayout and if animating ConstraintLayout would be tricky. Both of these concerns are without foundation:
The first thing worth noting about ConstraintLayout is that (although we don’t yet have the sources for ConstraintLayout, you can see a decompilation if you expand
classes.jar in the
constraint-layout-1.0.0-alpha2 external library in Android Studio Project view) it extends ViewGroup. That is quite important because so do all of the more traditional layouts which play extremely well with CoordinatorLayout. Furthermore, if you actually create a new Basic Activity using the New Android Activity wizard (
Right click module|New...|Activity|Basic Activity) then the wizard will automatically create your ConstraintLayout for the main content inside a CoordinatorLayout and you can assign behaviours to the ConstraintLayout exactly as you can with other layouts.
So what about animating ConstraintLayout? Once again it is simply a ViewGroup so it (and its children) can be animated in exactly the same way as any other ViewGroup. If this doesn’t immediately answer the question for you, then let’s step back to layouts 101 and recap on how layouts and Views actually work. A layout is simply a ViewGroup which is responsible for positioning its child Views. Before we can draw the layout and its children we first need to run a layout pass to calculate and set the positions and sizes of the child Views. Typically this will consist of an initial measurement pass to determine the intrinsic sizes of the child Views, and then calculate the position and size of each child before setting the
mBottom values for each child relative to the parent. Once the layout pass has been completed then each of the child Views has its bounds set internally, so when we come to draw the layout, simply calling onDraw() on each child will result in it being drawn at the correct position and size.
When we come to animating things, we don’t want to make changes to the layout itself because running a layout pass for each frame of the animation would be too expensive and kill our frame-rates. Instead we perform the layout pass before setting up the animation, and simply animate the positions of individual child Views by changing their
translationZ attributes (calling
setX() on a View will actually change its
translationX value and not its
mLeft value, for example). So it doesn’t actually matter which parent layout a particular View has, when we come to animate it all that matters is that the parent layout has calculated its
mBottom values already.
So now if we consider CoordinatorLayout again, it should be even clearer that any animations which run as a result of CoordinatorLayout behaviour implementations are completely agnostic of whether we use ConstraintLayout compared to any other layout.
Hopefully it should now be clear that ConstraintLayout will behave no differently to other layouts when it comes to performing animations – it simply runs in advance of any animations being set up, and when setting up the animations the actual parent layout that was responsible for positioning and sizing a specific child View is completely irrelevant.
So with some myths and concerns dispelled, in the next article we’ll begin looking in to ConstraintLayout and see how it works.
© 2016, Mark Allison. All rights reserved.
ConstraintLayout – Part 1 by Styling Android is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at http://blog.stylingandroid.com/license-information.