introduce

ConstraintLayout was introduced in Google IO 2016 to solve the problem of having too many complex page layers nested in development — too many layers can increase the time it takes to draw an interface and affect the user experience.

In use, ConstraintLayout can be thought of as a more powerful RelativeLayout that provides more apis to constrain the relative relationships of controls, making it easier to fit complex page layouts.

The layout properties

Constraint layout has more powerful constraint ability, it has a very large number of layout attributes, the author here to classify the explanation.

Relative positioning attribute

Relative positioning is one of the basic properties for creating layouts in constrained layouts. These properties are similar to the RelativeLayout layout property and are used to control the position of a control relative to another control or parent container.

Controls can be constrained on horizontal and vertical axes, respectively:

  • Horizontal: left, right, start, end
  • Vertical: top, bottom, text baseline

In simple terms, a control that needs to be constrained on a given side is constrained on another side of a control. For example, put button B to the right of button A:

We can write this:

<Button android:id="@+id/buttonA" . />
<Button android:id="@+id/buttonB" .
app:layout_constraintLeft_toRightOf="@+id/buttonA" />
Copy the code

In addition to specifying another control ID to constrain, we can also constrain the parent layout:

<Button android:id="@+id/buttonB" .
app:layout_constraintLeft_toLeftOf="parent" />
Copy the code

Margins

Constraint

_toXXXOf constraint

_toXXXOf constraint

_toXXXOf constraint

_toXXXOf constraint



Different from the other controls, a series of goneMargin properties are added to control the spacing values set when constraint target visibility is GONE.

One scenario requirement that the author can think of in practice is:

In the animation, when A is not visible, it is necessary to ensure that the layout position of B remains the same. In this case, the value of goneMarginStart is set to the width of A plus the marginStart of B to meet this requirement.

In the middle and Bias,

In the middle

As with other layouts, constrained layouts also have the ability to center child controls, and center the layout with horizontal/vertical constraints at the same time. For example, center A in the parent container:

<android.support.constraint.ConstraintLayout .>
  <Button android:id="@+id/button" .
          app:layout_constraintLeft_toLeftOf="parent"
          app:layout_constraintRight_toRightOf="parent/>
</>
Copy the code

Same thing with the vertical center.

Bias

The above layout constraints center the controls, which can be offset using bias.

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias

If bias is not set, the left and right values have 50% of each value, which is the middle effect. If bias is set to 0.3 (30%), the left margin will be reduced and the right margin will be increased accordingly.

Add app layout_constraintHorizontal_bias=”0.3″ to the above code to get the image effect.

<android.support.constraint.ConstraintLayout .>
  <Button android:id="@+id/button" .
          app:layout_constraintHorizontal_bias="0.3"
          app:layout_constraintLeft_toLeftOf="parent"
          app:layout_constraintRight_toRightOf="parent/>
</>
Copy the code

Relative circumferential positioning (VER 1.1)

The constraintCircle attribute, added in version 1.1, provides the developer the ability to constrain another control at an Angle and distance from the center of the control.

  • layout_constraintCircle
  • layout_constraintCircleRadius
  • layout_constraintCircleAngle

<Button android:id="@+id/buttonA" . />
<Button android:id="@+id/buttonB" .
        app:layout_constraintCircle="@+id/buttonA"
        app:layout_constraintCircleRadius="100dp"
        app:layout_constraintCircleAngle="45" />
Copy the code

Control size constraints

Setting the height and width of the control in ConstraintLayout is specified by Android :layout_width and Android :layout_height, but there are three different types:

  1. Use a certain size, given a value, for example36dp
  2. useWRAP_CONTENTThis effect is the same as the other controls
  3. use0dpTo represent theMATCH_CONSTRAINT, meaning to specify the height and width according to the constraint rules

(a) Set to WRAP_CONTENT; (b) Set to 0dp; (c) is (b) when margin is set

WRAP_CONTENTMandatory constraints under (VER 1.1)

Prior to version 1.1, the constraint layout did not limit the size of a control’s WRAP_CONTENT. So if you want to use WRAP_CONTENT but still need to enforce constraints to limit its results, you might want to add the following attributes:

  • app:layout_constrainedWidth=”true|false”
  • app:layout_constrainedHeight=”true|false”

The use scenario for this property is specified in the first example of the final business exercise

Wide high percentage

Layout_constraintDimensionRatio Limits the aspect ratio of the control. If you want to use the aspect ratio to constrain the size, set at least one of the dimensions to 0DP and then set the upper layout_constraintDimentionRatio property.

<Button android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1" />
Copy the code

The above code results in a Button with the same height and width.

There are two ways to evaluate the ratio:

  • Float value representing the ratio of width to height
  • Width: Height This ratio value, such as 9:16

You can also use aspect ratios if both dimensions are MATCH_CONSTRAINT (0DP), in which case the system uses the maximum dimension that satisfies all constraints and aspect ratios. If you want to constrain one dimension to the other, you can constrain the width or height by adding “W/H” to the ratio number. Example: the app: layout_constraintDimensionRatio = “H, 16:9.” “

This line of code represents the height of the constraint View, and its value needs to conform to a 16:9 ratio.

The chain

Chains provide a grouplike concept for multiple controls in the same direction (horizontal or vertical). The other directions can be controlled separately.

Create a chain

You can create a Chain when multiple controls reference each other in the same direction.

Chain Style

The following attributes are used to control Chain Style:

– layout_constraintHorizontal_chainStyle – layout_constraintHorizontal_weight – layout_constraintVertical_chainStyle – layout_constraintVertical_weight

There are four styles:

  1. CHAIN_SPREADThis is the default Style in which all controls are spread out
  2. In the Weighted chainCHAIN_SPREADIf the size of some controls is set toMATCH_CONSTRAINT (0 dp), the control size will take up all the remaining available space, similar to the LinearLayout weight.
  3. CHAIN_SPREAD_INSIDECHAIN_SPREADSimilar, except that the two controls at both ends and the parent container do not take up the extra space directly, and the extra space is scattered between the controls
  4. CHAIN_PACKEDIn this mode, all controls are clustered together in the center, but you can set bias to control where they are clustered.

Auxiliary layout

Guideline

Guideline is a special auxiliary layout class in constraint layout that allows you to create horizontal or vertical guides that other controls can use to layout. The Guideline is essentially an invisible control.

Position properties of the guide:

  • orientation:vertical/horizontal
  • Layout_constraintGuide_begin Specifies a fixed position from the left/top start
  • Layout_constraintGuide_end Specifies a fixed position from the start to the right/bottom
  • Layout_constraintGuide_percent specifies the percentage that is located in the layout

Barrier

Barrier refers to multiple controls in a constraint layout by constraint_referenced_ids, which adds a maximum width/height constraint to one control as a whole.

Determines the direction of the Barrier using the app:barrierDirection property.

 <android.support.constraint.Barrier
          android:id="@+id/barrier"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          app:barrierDirection="start"
          app:constraint_referenced_ids="button1,button2" />
Copy the code

Group

Groups are constraint layouts used to control the visibility of a set of controls.

<android.support.constraint.Group
    android:id="@+id/group"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="visible"
    app:constraint_referenced_ids="button4,button9" />
Copy the code

The visibility and elevation properties of the control referenced by id are the same as those of the Group.

In other words: controls referenced by the Group cause their own visibility and depth to lapse.

Classic business scenario

1. Fix one side with variable width in the middle and the other side following the middle tail

Design requirements: The avatar position is fixed, the length of the text in the middle is variable, and the right-most button follows the text to the right, but cannot exceed the screen.

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="60dp"
      tools:background="@color/background_gray">

      <ImageView
          android:id="@+id/iv_avatar"
          android:layout_width="40dp"
          android:layout_height="40dp"
          android:layout_marginStart="15dp"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintHorizontal_bias="0"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent"
          tools:srcCompat="@tools:sample/avatars[2]" />

      <TextView
          android:id="@+id/tv_text"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_marginStart="15dp"
          android:layout_marginEnd="15dp"
          android:singleLine="true"
          app:layout_constrainedWidth="true"
          app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
          app:layout_constraintEnd_toStartOf="@id/tv_action"
          app:layout_constraintHorizontal_bias="0"
          app:layout_constraintHorizontal_chainStyle="packed"
          app:layout_constraintStart_toEndOf="@id/iv_avatar"
          app:layout_constraintTop_toTopOf="@+id/iv_avatar"
          tools:text="ConstraintLayout is available as a support library" />

      <TextView
          android:id="@+id/tv_action"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_marginEnd="15dp"
          app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toEndOf="@id/tv_text"
          app:layout_constraintTop_toTopOf="@+id/iv_avatar"
          tools:text="View" />


</androidx.constraintlayout.widget.ConstraintLayout>

Copy the code

This scenario focuses on familiarity with the attribute: layout_constrainedWidth/Height application.

2. Center a group of views according to their height/width

Design requirements: the picture and text on the right should be centered with the head picture on the left.

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    tools:background="@color/background_gray">

    <ImageView
        android:id="@+id/iv_avatar"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginStart="15dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.3"
        tools:srcCompat="@tools:sample/avatars[2]" />

    <ImageView
        android:id="@+id/iv_pic"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginStart="50dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toTopOf="@+id/tv_content"
        app:layout_constraintStart_toEndOf="@id/iv_avatar"
        app:layout_constraintTop_toTopOf="@id/iv_avatar"
        app:layout_constraintVertical_chainStyle="packed"
        tools:srcCompat="@tools:sample/backgrounds/scenic[6]" />

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@id/iv_pic"
        app:layout_constraintTop_toBottomOf="@+id/iv_pic"
        tools:text="Chains provide group-like behavior in a single axis (horizontally or vertically). " />
</androidx.constraintlayout.widget.ConstraintLayout>

Copy the code

In this scenario, you must be familiar with the application of Chain. Iv_pic and TV_content are bidirectionally dependent. Packed Style is used to make them close together. Meanwhile, the head of IV_PIC is aligned with the head of IV_AVATAR, and the bottom of TV_content is aligned with the bottom of IV_AVATAR. So that they’re centered.