ConstraintLayout usually use, intermittent, are basically used in their own small demo. The company’s project has not been used yet. This company project needed a major overhaul, and I decided to use the nice layout. Reduce nesting (the old code was too deeply nested…. Powerless to ridicule).

First,ConstraintLayout is a new layout that inherits directly from ViewGroup, so it is very compatible. Officially, it is compatible with API 9. It is safe to eat.

One, the Relative positioning

Let’s start with a simple example:

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 1"/>

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/btn1"
        android:text="Button 2"/>

</android.support.constraint.ConstraintLayout>
Copy the code

It has a simple property :layout_constraintLeft_toRightOf, which puts button 2 to the left of button 1. Without this property, the two buttons would overlap, like FrameLayout.

There are many more properties like this:

Layout_constraintLeft_toLeftOf My left is aligned with your left layout_constraintLeft_toRightOf My left is aligned with your right layout_constraintRight_toLeftOf My right is aligned with your left layout_constraintRight_toRightOf My right is aligned with your right layout_constraintTop_toTopOf My top is aligned with your top Layout_constrainttop_totopof my top aligned with your bottom (equivalent to me being under you) layout_constraintBottom_toTopOf Layout_constraintBottom_toBottomOf layout_constraintBaseline_toBaselineOf baseline alignment layout_constraintStart_toEndOf My left is aligned with your right layout_constraintStart_toStartOf layout_constraintEnd_toStartOf layout_constraintEnd_toEndOfCopy the code

All of the above properties are fairly understandable, except for a relatively unfamiliar one: layout_constraintBaseline_toBaselineOf baseline alignment. Let’s go to the code:

 <TextView
        android:id="@+id/btn1"
        android:text="Button 1"
        android:textSize="26sp"/>

    <TextView
        android:id="@+id/btn2"
        android:text="Button 2"
        app:layout_constraintBaseline_toBaselineOf="@+id/btn1"
        app:layout_constraintLeft_toRightOf="@+id/btn1"/>
Copy the code

At a glance, the text equivalent of the baseline is aligned. If we don’t add layout_constraintBaseline_toBaselineOf, it would look something like this:

Second, align with the father’s edge

When a child view needs to be placed at the bottom or right of the parent view. We use:

<android.support.constraint.ConstraintLayout
        app:layout_constraintEnd_toEndOf="parent">

        <TextView
            android:text="Button 2"
            app:layout_constraintBottom_toBottomOf="parent"/>

    </android.support.constraint.ConstraintLayout>
Copy the code

app:layout_constraintBottom_toBottomOf="parent"My bottom is aligned with dad's bottom app:layout_constraintTop_toTopOf="parent"My top is aligned with dad's top app:layout_constraintLeft_toLeftOf="parent"My left is aligned with my father's left app:layout_constraintRight_toRightOf="parent"My right is aligned with my father's rightCopy the code

Third, center alignment

The TextView below, it’s aligned to the left of the father, it’s aligned to the right of the father, so, right most, it’s horizontally centered.

<TextView
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
Copy the code

As you may have guessed, center alignment is a combination of two alignments. The final effect. Such as:

This is vertically centered app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
Copy the code
In the middle of the father app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
Copy the code

Fourth, margins

The margins are the same as they were before.

android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
Copy the code

Here’s an example:

<TextView
    android:id="@+id/btn1"
    android:text="Button 1"
    android:textSize="26sp"/>
<TextView
    android:id="@+id/btn2"
    android:text="Button 2"
    android:layout_marginStart="40dp"
    app:layout_constraintLeft_toRightOf="@+id/btn1"/>
Copy the code

The effect is as follows:

例 句 : I have a Bias in favour of one side.

The horizontal center above is used to align with the left of the father + align with the right of the father. You can think of it as a constraint on the left and the right. By default, the left and the right are equally strong, so the view is centered.

When the left is more forceful, the view will be tilted to the left. It’s going to look like this.

When we need to change this binding, we need to use the following attributes:

Layout_constraintHorizontal_bias Horizontal binding layout_constraintVertical_bias Vertical bindingCopy the code

Here’s an example:

< android support. The constraint. ConstraintLayout < Button android: text = "Button 1" app: layout_constraintHorizontal_bias = "0.3" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> </android.support.constraint.ConstraintLayout>Copy the code

As you can see, there are two restraint lines on the left and right. The left side is shorter. So it’s biased to the left

5. Circular Positioning (Added in 1.1)

The positioning of the circle?

This is a cool one, you can constrain the center of one view in terms of Angle and distance relative to the center of another view,

It might be abstract, but take a look at Google’s picture:

His attributes are:

Layout_constraintCircle: refers to another widget ID layout_constraintCircleRadius: Distance from the center of other widgets layout_constraintCircleAngle: Which Angle the widget should be at (in degrees, from 0 to 360)Copy the code

Here’s an example:

<Button
    android:id="@+id/btn1"
    android:text="Button 1"/>
<Button
    android:text="Button 2"
    app:layout_constraintCircle="@+id/btn1"
    app:layout_constraintCircleRadius="100dp"
    app:layout_constraintCircleAngle="145"/>
Copy the code

Visibility behavior

When a View is set to Gone in ConstraintLayout, you can treat it as a point (all margins of the View are invalid). This point is assumed to be real.

Here’s an example:

<Button
    android:id="@+id/btn1"
    android:text="Button 1"
    android:textSize="26sp"/>


<Button
    android:id="@+id/btn2"
    android:layout_marginStart="20dp"
    android:text="Button 2"
    android:visibility="gone"
    app:layout_constraintLeft_toRightOf="@+id/btn1"/>

<Button
    android:id="@+id/btn3"
    android:layout_marginStart="20dp"
    android:text="Button 3"
    app:layout_constraintLeft_toRightOf="@+id/btn2"/>
Copy the code

As you can see, the margin between button 3 and button 1 is only 20.

Here’s another example:

 <Button
    android:id="@+id/btn2"
    android:layout_marginStart="20dp"
    android:text="Button 2"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

<Button
    android:id="@+id/btn3"
    android:text="Button 3"
    app:layout_constraintLeft_toRightOf="@+id/btn2"
    app:layout_constraintTop_toTopOf="@+id/btn2"
    app:layout_constraintBottom_toBottomOf="@+id/btn2"/>
Copy the code

I placed button 3 to the right of button 2, but I did not add Android :visibility=”gone” to button 2.

Now let’s add android: Visibility =”gone” to button 2.

At this point, button 2 shrinks to a point, so button 3 is still on his right side.

7. Dimensions constraints

ConstraintLayout in ConstraintLayout, you can set the minimum and maximum size for a view.

The attributes are as follows (these will only take effect if the given width or height is WRap_content):

Android :minWidth Sets the minimum width of the layout. Android :minHeight Sets the minimum height of the layout. Android :maxWidth Sets the maximum width of the layoutCopy the code

Widgets Dimension constraints

We usually use Android :layout_width and Android :layout_height to specify the width and height of the view.

The same is true for ConstraintLayout, but with an extra 0DP.

  • Use lengths, such as
  • Using wrap_content, the view calculates its own size
  • Use 0dp, equivalent to “MATCH_CONSTRAINT”

Here’s an example

<Button
    android:id="@+id/btn1"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:text="Button 1"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"/>

<Button
    android:id="@+id/btn2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button 2"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/btn1"/>


<Button
    android:id="@+id/btn3"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="60dp"
    android:text="Button 3"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/btn2"/>
Copy the code

On display:

9. WRAP_CONTENT: Mandatory constraints (added in 1.1)

When the width or height of a view is set to wrap_content, the constraint becomes problematic if the content is really wide. Let’s look at a little chestnut:

<Button
    android:id="@+id/btn1"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:text="Q"/>

<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"
    app:layout_constraintLeft_toRightOf="@id/btn1"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/btn1"/>
Copy the code

As you can see from the image on the right, the contents of button 2 are indeed to the right of the contents of button 1. But button 2, as a whole, is not entirely to the right of button 1.

The following two properties are needed

App: layout_constrainedWidth ="true|false"App: layout_constrainedHeight ="true|false"Copy the code

Add an app to button 2 :layout_constrainedWidth=”true”.

Ha ha, see the effect we want again. Cool, dropping.

10. MATCH_CONSTRAINT size (added in 1.1)

When the width and length of a view is set to MATCH_CONSTRAINT(that is, 0dp), the default is to make the view take up all available space. There are a couple of additional properties here

Layout_constraintWidth_min and layout_constraintHeight_min: Set the minimum size for this dimension layout_constraintWidth_max and layout_constraintHeight_max: Sets the maximum size for this dimension layout_constraintWidth_percent and layout_constraintHeight_percent: sets the size of this dimension to the percentage of the parentCopy the code

Here’s a simple percentage example: center and the view is half the width of the father

 <Button
    android:id="@+id/btn1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Q"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintWidth_percent="0.5"/>
Copy the code

It’s so easy! This greatly reduced our workload.

Pay attention to

  • The percentage layout must be used with MATCH_CONSTRAINT(0DP)
  • Layout_constraintWidth_percent or layout_constraintHeight_percentProperty to a value between 0 and 1

11. Set width and height according to Ratio.

Can set up the View of the wide high proportion, will need at least one constraint dimension is set to 0 dp (namely MATCH_CONSTRAINT), set layout_constraintDimensionRatio again.

For example:

<Button
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:text="Button"
    app:layout_constraintDimensionRatio="16:9"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>
Copy the code

The ratio can be expressed as:

  • Floating point value representing the ratio between width and height
  • Ratio of the width to height form

Ratios can also be used if both sizes are set to MATCH_CONSTRAINT (0DP). In this case, the system sets the maximum size that satisfies all the constraints and retains the specified aspect ratio. To limit one particular edge based on the size of another particular edge, you can preattach W, “or” H, constraining width or height, respectively. For example, if a size is constrained by two targets (for example, width 0dp and centered on the parent node), you can indicate which side should be constrained by adding the letter W (for the constraint width) or H (for the constraint height) before the ratios, separating them by commas:

<Button android:layout_width="0dp"
   android:layout_height="0dp"
   app:layout_constraintDimensionRatio="H,16:9"
   app:layout_constraintBottom_toBottomOf="parent"
   app:layout_constraintTop_toTopOf="parent"/>
Copy the code

The code above sets the height of the button in a ratio of 16:9, and the width of the button matches the parent constraint.

What are the Chains?

When the attribute layout_constraintHorizontal_chainStyle or layout_constraintVertical_chainStyle is set to the first element of the chain, the behavior of the chain changes according to the specified style (default: CHAIN_SPREAD).

  • CHAIN_SPREAD – Element will expand (default style)
  • The weighted link CHAIN_SPREAD pattern, where some widgets MATCH_CONSTRAINT are set that split the available space
  • CHAIN_SPREAD_INSIDE – Similar, but the ends of the chain are not spread out
  • CHAIN_PACKED – The elements of the chain will be packed together. Then, the horizontal or vertical deviation attribute of the child will affect the positioning of the packaged element

Here is a weight effect similar to a LinearLayout, using the layout_constraintHorizontal_weight attribute:

<Button
    android:id="@+id/btn1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="A"
    app:layout_constraintEnd_toStartOf="@id/btn2"
    app:layout_constraintHorizontal_chainStyle="spread"
    app:layout_constraintHorizontal_weight="1"
    app:layout_constraintStart_toStartOf="parent"/>


<Button
    android:id="@+id/btn2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button 2"
    app:layout_constraintEnd_toStartOf="@id/btn3"
    app:layout_constraintHorizontal_weight="2"
    app:layout_constraintStart_toEndOf="@id/btn1"/>

<Button
    android:id="@+id/btn3"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Ask"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_weight="3"
    app:layout_constraintStart_toEndOf="@id/btn2"/>
Copy the code

A rendering of the example is shown below:

13, Guideline,

This is a virtual view

Guideline can create horizontal or vertical lines relative to ConstraintLayout. This guide, sometimes it helps us locate.

Layout_constraintGuide_begin Distance from the father's starting position (left or top) Layout_constraintGuide_percent Percentage of width or height from the father (value range 0-1)Copy the code

What are we doing with the guides?? Sometimes, for example, there might be a need to have two buttons, one left and one right in the center of the screen. In the old days, I would take a LinearLayout, and then center the LinearLayout, and then push left and right.

The renderings are as follows:

Now we use the Guideline, it’s super convenient, look at the code:

<! -- Horizontal center -->
<android.support.constraint.Guideline
    android:id="@+id/gl_center"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.5"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button 1"
    app:layout_constraintEnd_toStartOf="@id/gl_center"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button 2"
    app:layout_constraintLeft_toRightOf="@id/gl_center"/>
Copy the code

14, the Barrier

Virtual view

A Barrier is something like a Barrier. It’s more flexible than the Guideline. It can be used to constrain multiple views.

For example, the following name and contact information, the EditText on the right must be aligned to the left, and the two TextViews on the left can be viewed as a whole, with the Barrier to the right of the widest TextView, and the EditText on the right to the right of the Barrier.

A Barrier has two properties

  • The value of barrierDirection can be top, bottom, left, right, start, or end, which controls the position of the Barrier relative to the given View. For example, in the chestnuts above, the Barrier should be right of the name TextView, so the value is right (or end, if you like). This problem with right and end actually shows up in a RelativeLayout, where you get a warning when you write a RelativeLayout left or right, and you get start and end.
  • Constraint_referenced_ids, the value is the id of the control to depend on (no @+id/ is required). The Barrier will use the width (height) of the largest ids as its position.

Ps: There’s a little bit of a hole in this thing, if you write the code and it’s fine, but the preview isn’t what you want. At this point, run the program. Then the preview is normal, and the display on the phone is normal.

The code for the example is as follows (if the preview is incorrect, be sure to run it, and do not suspect that your code is wrong):

<TextView
    android:id="@+id/tv_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Name:"
    app:layout_constraintBottom_toBottomOf="@id/tvTitleText"/>

<TextView
    android:id="@+id/tv_phone"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Contact information :"
    app:layout_constraintBottom_toBottomOf="@id/tvContentText"
    app:layout_constraintTop_toBottomOf="@+id/tv_name"/>

<EditText
    android:id="@+id/tvTitleText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="null"
    android:text="Zhang"
    android:textSize="14sp"
    app:layout_constraintStart_toEndOf="@+id/barrier2"/>

<EditText
    android:id="@+id/tvContentText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="null"
    android:text="xxxxxxxxxxxxxxx"
    android:textSize="14sp"
    app:layout_constraintStart_toEndOf="@+id/barrier2"
    app:layout_constraintTop_toBottomOf="@+id/tvTitleText"/>

<android.support.constraint.Barrier
    android:id="@+id/barrier2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:barrierDirection="right"
    app:constraint_referenced_ids="tv_name,tv_phone"/>
Copy the code

15 and Group

Fixed magic, this is a group. This is also a virtual view.

You can put views in there, and then the Group can control the hiding of those views at the same time.

<android.support.constraint.Group
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    app:constraint_referenced_ids="btn1,btn2"/>

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button 1"/>

<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button 2"
    app:layout_constraintTop_toBottomOf="@id/btn1"/>
Copy the code
  • Group has an attributeconstraint_referenced_idsYou can throw in views that you want to hide at the same time.
  • Don’t wrap a view around a Group. This will cause an error because Group is just a View that does not execute onDraw().
  • When using multiple groups, try not to put a View in multiple groups repeatedly, because actual measurement may lead to hidden failure.

What is a virtual view

The virtual views listed above are:

  • Guideline
  • Barrier
  • Group

Let’s look at the source code

//Guideline

public class Guideline extends View {
public Guideline(Context context) {
    super(context);
    // What is this 8?
    //public static final int GONE = 0x00000008;
    // This is the value of view. GONE
    super.setVisibility(8);
}

public Guideline(Context context, AttributeSet attrs) {
    super(context, attrs);
    super.setVisibility(8);
}

public Guideline(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    super.setVisibility(8);
}

public Guideline(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr);
    super.setVisibility(8);
}

// The visibility is always GONE
public void setVisibility(int visibility) {}// No painting
public void draw(Canvas canvas) {}// Size is always 0
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    this.setMeasuredDimension(0.0);
}
Copy the code

We see the Guideline is actually a normal View, and we set ourselves to GONE in the constructor

  • If setVisibility() is an empty method, the View will always be GONE.
  • The draw() method is empty, meaning you don’t have to draw.
  • OnMeasure () sets its width and length to 0.

To sum up, I think this Guideline is invisible and does not require measurement or drawing, so we can ignore its drawing consumption.

ConstraintHelper is a View.ConstraintHelper’s onDraw() and onMeasure() are as follows:

public void onDraw(Canvas canvas) {}protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //mUseViewMeasure is always false, but it is used in the Group, but it is set to false.
    if (this.mUseViewMeasure) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    } else {
        this.setMeasuredDimension(0.0); }}Copy the code

The Guideline is the same, or you can ignore the performance cost. The above mUseViewMeasure is always false, so the length and width are always 0.

So we can think of Guideline,Barrier, and Group as virtual attempts, because they rarely cause much drawing performance loss. This is how I understand it.

Optimizer (Add in 1.1)

You can determine which optimizations to apply by adding the tag app: layout_optimizationLevel element to ConstraintLayout. I feel this is still in the experimental stage, so don’t use… Ha ha

The usage is as follows:

<android.support.constraint.ConstraintLayout 
    app:layout_optimizationLevel="standard|dimensions|chains"
Copy the code
  • None: indicates that no optimization is performed
  • Standard: By default, only direct and obstacle constraints are optimized
  • Direct: Optimizes the direct constraint
  • Barrier: Optimizes the constraint of obstacles
  • Chain: optimizes the chain constraints
  • Dimensions: Optimized dimension measurements to reduce the number of measurements for matching constraint elements

conclusion

I have listed some commonly used properties and how to use them, so that you can refer to them. If there is something wrong, please correct me.