Page 1 of 5
Like it or loathe it you have to come to terms with the ConstraintLayout. It is Google's preferred way of doing things and Android Studio's Designer and other features are tailored to making it easy to work with, at the expense of the other layouts.
Android Programming In Java:
Starting With an App
Is now available in paperback and ebook.
Available from Amazon.
- Getting Started With Android Studio 3
- The Activity And The UI
- Building The UI and a Calculator App
- Android Events
Extract: Using Lambdas
- Basic Controls
- Layout Containers
- The ConstraintLayout
Extract: Guidelines and Barriers
- UI Graphics A Deep Dive
Extract: Programming the UI ***NEW
- Menus & The Action Bar
- Menus, Context & Popup
- Beginning Bitmap Graphics
Extract: Simple Animation
- Staying Alive! Lifecycle & State
- ListView And Adapters
If you are interested in creating custom template also see:
Custom Projects In Android Studio
The ConstraintLayout was new in Android Studio 2.2 and it makes use of an additional library that is added when you select it in the palette. The support library is compatible with all versions of Android back to Gingerbread (2.3, API level 9) and so you can use the ConstraintLayout unless you plan targeting devices running earlier than Gingerbread.
It was introduced in an effort to make layout more responsive to screen size changes and to improve the efficiency of layout by making it possible to avoid nesting layouts. It is, essentially, an improved RelativeLayout and if you have read the section on the RelativeLayout much of what follows wiil seem familiar. The layout editor has been changed to work well with the ConstraintLayout at the cost of making the other layouts harder to work with - presumably this will change as Android Studio continues to develope.
If you have an existing layout then you can ask Android Studio to convert it to ConstraintLayout. All you have to do is right click on the layout used in the Component Tree and select Convert to ConstraintLayout. This can be used to reduce a nested layout to a single "flat" ContstraintLayout but be warned in practice it often gets things very wrong. Often the best you can say of a converted layout is that it provides a starting point for reimplemenation.
Let's take a look at how the ConstraintLayout works in the layout editor.
If you drag a button onto the layout the Designer will give you information about alignments with other controls and the parent in much the same way that it does for the RelativeLayout.
However, unlike the RelativeLayout the designer doesn't add any possitioning to the control as you move it around. Any positioning information is only to help you locate UI components relative to the existing layout.
With the new constraint layout where you drop a component has no effect on where is will show when the app is run. In fact if you simply drop a UI component on the design surface without applying any constraints then when you run the app the component will drift up to the top left hand corner.
Notice that this means that where the component will appear in the running app isn't the same as where it appears to be positioned on the design surface and this can be confusing.
Using the constraint layout the only thing that affects where a component displays are the constraints you apply.
So how do you apply a constraint?
You can have the Designer suggest them for you automatically or you can apply them manually.
Automatic constraints are the easiest to use and there are two ways to get the editor to apply constraints dynamically - the autoconnect mode and for the entire layout - infer constraints. They do slightly different things and you need to learn to make them work together.
The autoconnect mode seems the most useful when you first meet it, but in practice it can be confusing and error prone. However it is worth trying out. To turn autoconnect on simply click the autoconnect icon on at the top of the Designer:
As already explained in Chapter 3, Autoconnect applies constraints to a single component that you are either placing on the design surface for the first time or to a component that doesn’t already have constraints applied that you drag to a new location. When a constraint is added Autoconnect doesn’t attempt to change it if you move the component to a new location where a different constraint might be more appropriate. As already discussed in Chapter 3 the other problem is that Autoconnect doesn’t add constraints that seem obvious. It adds constraints for centering and placing close to an edge but it doesn’t add any constraint relative to another component or just to generally position the component.
At the moment Autoconnect is a fairly weak feature and hardly worth turning on in most cases.
The Infer constraints option is, in many ways, easier to use and more powerful than Autoconnect. All you have to do is position the components where you want them and then click the Infer constraints icon:
At the time of writing there is a bug that makes Infer Constraints difficult to use. The Designer changes the layout_marginLeft and layout_marginRight properties as you drag a control to a new position. The Infer Constraints button sets layout_marginLeft and layout_marginRight but also layout_marginStart and layout_marginEnd which are the same as left and right if the directionality is left-to-right but reversed if it is right-to-left. The problem is that start and end take precedence over left and right and once Infer Constraints sets either one you cannot change the horizontal position by dragging and dropping.
The fix is to go to the Properties window and zero layout_marginStart and/or layout_marginEnd. When you do this constraints will be calculated based on where each component is currently located.
When you do this constraints will be calculated based on where each component is currently located. Only constraints that are necessary to fix the position of a component are added - existing constraint are not modified. This means you can use infer constraints to make sure that your layout has enough constraints to make it work - if none are added it was OK. It also mean that if you click Infer Constraints a second time nothing changes even if you have moved components. To get a new set of constraints you have to delete the constraints you want recomputed and then click Infer Constraints.
You can delete all of the constraints in a layout using the Clear All Constraints button:
A good strategy is to switch off the auto connect and use the infer constraints option every time you place a new component on the design surface. This allows you to build up a layout one component at a time and check each new set of constraints. You can then modify the newly added constraints and move on to the next component.