Android - ConstraintLayout (constraint layout)

1 Introduction

ConstraintLayout ConstraintLayout is a ViewGroup that can be used in Android systems above Api9. Its appearance is mainly to solve the problem of excessive nesting of layouts, and to position and adjust widgets in a flexible way. Starting from Android Studio 2.3, the official template uses ConstraintLayout by default.
Official documentation: ConstraintLayout

2. Basic attributes and their use

To define the position of a view in a ConstraintLayout, you must add at leasta horizontal constraintanda vertical constraint. Each constraint represents a connection or alignment to other views, parent layouts, or invisible guides. Each constraint defines the view's position on the vertical or horizontal axis; therefore each view must have at least one constraint on each axis, but often more are required.

2.1 Relative positioning

2.1.1 Properties

1. layout_constraintLeft_toLeftOf
   当前View的右侧和另一个View的右侧位置对齐
   与RelativeLayout的alignLeft属性相似
2. layout_constraintLeft_toRightOf 
   当前view的左侧会在另一个View的右侧位置
   与RelativeLayout的toRightOf属性相似
3. layout_constraintRight_toLeftOf 
   当前view的右侧会在另一个View的左侧位置 
   与RelativeLayout的toLeftOf属性相似
4. layout_constraintRight_toRightOf 
   当前View的右侧和另一个View的右侧位置对其
   与RelativeLayout的alignRight属性相似
5. layout_constraintTop_toTopOf 
   头部对齐,与alignTop相似
6. layout_constraintTop_toBottomOf 
   当前View在另一个View的下侧 与below相似
7. layout_constraintBottom_toTopOf 
   当前View在另一个View的上方 与above相似
8. layout_constraintBottom_toBottomOf 
   底部对齐,与alignBottom属性相似
9. layout_constraintBaseline_toBaselineOf 
   文字底部对齐,与alignBaseLine属性相似
10. layout_constraintStart_toEndOf 
   同left_toRightOf
11. layout_constraintStart_toStartOf 
   同left_toLeftOf
12. layout_constraintEnd_toStartOf 
   同right_toLeftOf
13. layout_constraintEnd_toEndOf 
   同right_toRightOf

Let’s look at a simple example first: (If we want to implement the following layout, the
insert image description here
code is as follows:

<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
    tools:context=".MainActivity">
    <TextView
        android:id="@+id/textView1"
        android:layout_width="100dp"
        android:layout_height="60dp"
        android:background="#D6E1AA"
        android:gravity="center"
        android:text="textview1"
        android:textColor="@color/black"
        android:textSize="25sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="138dp"
        android:layout_height="111dp"
        android:background="#E8C99B"
        android:gravity="center"
        android:text="textview2"
        android:textColor="@color/black"
        android:textSize="25sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="@+id/textView1"
        app:layout_constraintEnd_toStartOf="@+id/textView1"
        tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>

The most important two lines of code in textview2:

 app:layout_constraintBottom_toBottomOf="@+id/textView1"
 app:layout_constraintEnd_toStartOf="@+id/textView1"

We align the bottom of textview2 with the bottom of textview1, and align the right side of textview2 with the left side of textview1 to determine the position of textview2.

There is a more interesting attribute: layout_constraintBaseline_toBaselineOf
Baseline refers to the text baseline, which can be realized by changing the above xml code.

    <TextView
        android:id="@+id/textView1"
        .../>
    <TextView
        android:id="@+id/textView2"
        ...
        app:layout_constraintLeft_toRightOf="@+id/textView1" 
        app:layout_constraintBaseline_toBaselineOf="@+id/textView1"
        />

insert image description here
You can see that we align the text baselines of textview1 and textview2.

  • The relative positioning of ConstraintLayout is similar to that of RelativeLayout. Here is a picture to summarize relative positioning:
    insert image description here

2.2 Angle positioning

One widget center can be constrained relative to another widget center at an angle and distance. This allows you to position a widget on a circle.
insert image description here

2.2.1 Properties

layout_constraintCircle : 引用另一个小部件 id
layout_constraintCircleRadius : 到另一个小部件中心的距离
layout_constraintCircleAngle : 小部件应该在哪个角度(以度为单位,从 0 到 
    <TextView
        android:id="@+id/textView1"
        .../>
    <TextView
        android:id="@+id/textView2"
        ...
        app:layout_constraintCircle="@+id/textView1"
        app:layout_constraintCircleAngle="120"
        app:layout_constraintCircleRadius="150dp"
        />

insert image description here
It means that the center of TextView2 is 120 degrees from the center of TextView1, and the distance is 150dp.

2.3 Margins

2.3.1 Properties

android:layout_marginStart //距离开始
android:layout_marginEnd //距离结束
android:layout_marginLeft //距离左边
android:layout_marginTop //距离上边
android:layout_marginRight //距离右边
android:layout_marginBottom //距离下边
android:layout_marginBaseline //距离基线
  • It looks no different from other layouts, but in fact, to implement margin in ConstraintLayout, the control mustConstrain firstThe position of the control in ConstraintLayout, for example:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <TextView
        android:id="@+id/TextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#E8C99B"
        android:gravity="center"
        android:text="textview1"
        android:textColor="@color/black"
        android:textSize="25sp"
        android:textStyle="bold"
        android:layout_marginLeft="100dp"
        android:layout_marginTop="100dp"/>
</android.support.constraint.ConstraintLayout>

insert image description here
We will find that the textview does not have a margin of 100dp from the left and top of the border. In ConstraintLayout, it does not take effect because there is no constraint on the position of the textview in the layout.
The correct way to write it is as follows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <TextView
        android:id="@+id/TextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#E8C99B"
        android:gravity="center"
        android:text="textview1"
        android:textColor="@color/black"
        android:textSize="25sp"
        android:textStyle="bold"
        android:layout_marginLeft="100dp"
        android:layout_marginTop="100dp"
        
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
</android.support.constraint.ConstraintLayout>

Constrain the left and top of the textview to the left and top of the parent, so that the margin will take effect. The effect is as follows:
insert image description here
When using margin, pay attention to two points:

  1. Controls must constrain a relative position in the layout
  2. margin can only be greater than or equal to 0

2.3.2 Invisibility behavior (goneMargin)

goneMargin is mainly used for the margin value used when the visibility of the constraint control is set to gone. The properties are as follows:

layout_goneMarginStart //距离开始
layout_goneMarginEnd  
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <TextView
        android:id="@+id/textview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#E8C99B"
        android:gravity="center"
        android:text="textview1"
        android:textColor="@color/black"
        android:textSize="25sp"
        android:textStyle="bold"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
    <TextView
        android:id="@+id/textView2"
        android:layout_width="138dp"
        android:layout_height="111dp"
        android:background="#D6E1AA"
        android:gravity="center"
        android:text="textview2"
        android:textColor="@color/black"
        android:textSize="25sp"
        android:textStyle="bold"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/textview1"
        />
</android.support.constraint.ConstraintLayout>

The effect is as follows:
insert image description here
change the code

  1. Add to textview1:
android:visibility="gone"
  1. The corresponding constraints for textview2 are changed to:
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/textview1"
app:layout_goneMarginLeft="50dp"

In this way, after setting textview1 to be invisible, textview2 will be 50dp away from the left, and the effect is as follows:
insert image description here

2.4 Centering and offsetting

2.4.1 Centering

In RelativeLayout, the method of placing controls in the middle of the layout is:

android:layout_centerInParent="true"

The writing method in Constraintlayout is:

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"

It means to constrain the top, bottom, left, and right of the control to the top, bottom, left, and right of the layout, so that the control can be placed in the middle of the layout, and the effect is as follows.
insert image description here

2.4.2 Offset

layout_constraintHorizontal_bias //水平方向偏移
layout_constraintVertical_bias //垂直方向偏移

To display the effect, add a sentence to the xml code:

app:layout_constraintHorizontal_bias="0.3"
水平方向距父布局开始位置偏移百分之三十

insert image description here
At this time, we found that textvew1 has shifted horizontally.

2.5 Size constraints

2.5.1 Constraints

The size of a control can be specified in four different ways:

  1. use the specified size
  2. Use wrap_content to let the control calculate its own size
    When the height or width of the control is wrap_content, you can use the following properties to control the maximum and minimum height or width:

android:minWidth minimum width
android:minHeight minimum height
android:maxWidth maximum width
android:maxHeight maximum height

  1. Using 0dp (MATCH_CONSTRAINT)
    officially does not recommend using match_parent in ConstraintLayout. You can set 0dp (MATCH_CONSTRAINT) to match constraints instead of match_parent. For example:
<TextView
        android:id="@+id/TextView1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        ......
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

The width is set to 0dp, the left and right sides constrain the left and right sides of the parent, and the left margin is set to 50dp, the effect is as follows:
insert image description here

  1. Aspect Ratio
    When at least one dimension of width or height is set to 0dp, you can pass the attributelayout_constraintDimensionRatioSet the aspect ratio, for example:
<TextView
        android:id="@+id/TextView1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        ......
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constrainedWidth="true"
        app:layout_constrainedHeight="true"/>

insert image description here
In addition, when setting the value of the aspect ratio, you can also add W or H in front to specify the width or height limit respectively. For example:
app:layout_constraintDimensionRatio="H,2:3" refers to height: width=2:3
app:layout_constraintDimensionRatio="W,2:3" refers to width: height=2:3

  • important hint:
    MATCH_PARENT is deprecated for ConstraintLayout. Similar behavior can be defined by setting the corresponding left/right or top/bottom constraints to "parent" via MATCH_CONSTRAINT.

WRAP_CONTENT (added in 1.1): Enforce Constraints
If dimensions are set to WRAP_CONTENT, they will be treated as literal dimensions in versions prior to 1.1 -- that is, the constraint will not restrict the resulting dimension. You may wish to use WRAP_CONTENT, but continue to enforce constraints to limit the resulting dimensions. In this case, one of the corresponding properties can be added:

app:layout_constrainedWidth="true|false"
app:layout_constrainedHeight="true|false"

MATCH_CONSTRAINT dimension (added in 1.1)
When dimension is set to MATCH_CONSTRAINT, the default behavior is to have the result size occupy all available space. Several additional modifiers are available:

  1. layout_constraintWidth_min and layout_constraintHeight_min
    will set the minimum size for this dimension
  2. layout_constraintWidth_max and layout_constraintHeight_max
    will set the maximum size of this dimension
  3. layout_constraintWidth_percent and layout_constraintHeight_percent
    set the size of this dimension as a percentage of the parent dimension

2.6 chain

If two or more controls are constrained together as shown in the figure below, they can be considered as a chain (the picture shows a horizontal chain, and the same goes for the vertical).
Please add a picture description
Simple to use, expressed in code as:

    <TextView
        android:id="@+id/TextView1"
        ......
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/TextView2" />

    <TextView
        android:id="@+id/TextView2"
        ......
        app:layout_constraintLeft_toRightOf="@+id/TextView1"
        app:layout_constraintRight_toLeftOf="@+id/TextView3"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

    <TextView
        android:id="@+id/TextView3"
        ......
        app:layout_constraintLeft_toRightOf="@+id/TextView2"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

The three textviews are mutually constrained, and the two textviews at both ends are respectively constrained by the parent to form a chain. The first control of each chain is the chain header of the chain. We can set the layout_constraintHorizontal_chainStyle
insert image description here
property in the chain header to change the style of the entire chain.

chains provides 3 styles, namely:

  • spread expands the element (default)
  • spread_inside expands the element, but the two ends of the chain are close to the parent
  • The elements of the packet chain will be packed together.

The spread_inside
spread_inside
packet
insert image description here
example above creates a style chain, in addition to the style chain , a weight chain can also be created .
The width of the 3 textviews used above is wrap_content. If we set the width to 0dp, we can set the horizontal weight in each texttiew at this timelayout_constraintHorizontal_weight(constraintVertical is vertical) to create a weight chain, the xml code is as follows:

<TextView
        android:id="@+id/TextView1"
        android:layout_width="0dp"
        ......
        app:layout_constraintHorizontal_weight="2" />

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="0dp"
        ......
        app:layout_constraintHorizontal_weight="3" />

    <TextView
        android:id="@+id/TextView3"
        android:layout_width="0dp"
         ......
        app:layout_constraintHorizontal_weight="2" />

insert image description here

Guess you like

Origin blog.csdn.net/The_onion/article/details/127675500