ConstraintLayout introduction

ConstraintLayout is a ViewGroup which allows you to position and size widgets in a flexible way.

ConstraintLayout is now the default layout in AndroidStudio, and the website explains how to make the layout more flexible. This reduces nesting of layouts and improves UI rendering efficiency.

ConstraintLayout can flexibly locate and adjust the size of subviews, which depend on constraints to determine their position, and each subview must have at least one horizontal constraint and one vertical constraint. Each constraint represents how it is connected or aligned with other views, parent layouts, or invisible bootlines.

Gradle builds:

dependencies {
    implementation "Androidx. Constraintlayout: constraintlayout: 2.0.4."
}

Copy the code

Relative positioning

Layout_constraintXXX_toYYYOf attribute that sets constraints on the XXX direction of ViewA and YYY direction of ViewB. The value can be the ID of a control ViewB or ConstraintLayout itself, which is parent.

  • layout_constraintLeft_toLeftOf

  • layout_constraintLeft_toRightOf

  • layout_constraintRight_toLeftOf

  • layout_constraintRight_toRightOf

  • layout_constraintTop_toTopOf

  • layout_constraintTop_toBottomOf

  • layout_constraintBottom_toTopOf

  • layout_constraintBottom_toBottomOf

  • layout_constraintStart_toEndOf

  • layout_constraintStart_toStartOf

  • layout_constraintEnd_toStartOf

  • layout_constraintEnd_toEndOf

  • Layout_constraintBaseline_toBaselineOf // Often set the price of ¥99 this style

Margins

  • android:layout_marginStart
  • android:layout_marginEnd
  • android:layout_marginLeft
  • android:layout_marginTop
  • android:layout_marginRight
  • android:layout_marginBottom
  • layout_marginBaseline

Sample code:

<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/purple_200"
        android:text="I am tv1"
        android:gravity="center"
        android:textColor="#ffffff"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:background="@color/teal_200"
        android:text="I'm TV2. I'm centered."
        android:gravity="center"
        android:textColor="#fff"
        android:textSize="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv3"
        android:layout_width="100dp"
        android:layout_height="30dp"
        android:background="@color/purple_700"
        android:text="I am tv3"
        android:gravity="center"
        android:textColor="#fff"
        android:layout_marginLeft="10dp"
        app:layout_constraintBaseline_toBaselineOf="@+id/tv2"
        app:layout_constraintLeft_toRightOf="@+id/tv2" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Strong constraint

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias

Properties to set the horizontal and vertical offsets of the control. This means that you can adjust the horizontal or vertical proportions of a control if you add these properties to it after it has set a constraint. The value can be 0-1.

<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.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">


    <ImageView
        android:id="@+id/avatar2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:layout_marginLeft="15dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.8" />


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginEnd="32dp"
        android:layout_marginStart="10dp"
        android:background="@color/design_default_color_error"
        android:text="Text long text long text long text long text long text long text long text long text long text"
        android:textColor="@android:color/white"
        app:layout_constrainedWidth="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintStart_toEndOf="@+id/avatar2"
        app:layout_constraintTop_toTopOf="@+id/avatar2"
        tools:ignore="RtlCompat" />

    <ImageView
        android:id="@+id/avatar1"
        android:layout_marginLeft="15dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6" />


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginEnd="32dp"
        android:layout_marginStart="10dp"
        android:background="@color/design_default_color_error"
        android:text="Short text"
        android:textColor="@android:color/white"
        app:layout_constrainedWidth="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintStart_toEndOf="@+id/avatar1"
        app:layout_constraintTop_toTopOf="@+id/avatar1"
        tools:ignore="RtlCompat" />
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Pay attention to

  • The TextView constraint is between ImageView and ConstraintLayout. If the text is too short, it is centered. Layout_constraintHorizontal_bias =”0″ controls the TextView to be displayed to the left regardless of the length of the text.

  • App :layout_constrainedWidth=”true” confirms the width constraint, which, if not added, will squeeze out of the screen when too much text is added

Aspect ratio

Setting the aspect ratio of a control that used to be cumbersome is now much easier with the layout_constraintDimensionRatio attribute.

To use the layout_constraintDimensionRatio attribute, one of its width or height values needs to be knowable, and the remaining one is 0DP. Knowable, that is, the value already has explicit constraints. The width/height ratio of the control is set by “float value” or “Width: height”, indicating whether the scale value is calculated by width or height by adding w or h before the scale value.

This ratio can be divided into three cases:

  • Case 1:
W :0dp h:wrap_content/ Specific value By default, h is used as the standard to constrain W."w,2:1"="2:1"Width: height =2:1If you write at this time"h,2:1"Represents height: width =2:1;Copy the code
<? 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">


    <ImageView
        android:id="@+id/img3"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintDimensionRatio="w,2:1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <ImageView
        android:id="@+id/img4"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_marginTop="50dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintDimensionRatio="h,2:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/img3" />
    
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

  • Situation 2:
W :wrap_content/ h:0dp By default, h is constrained by W as the standard."h,2:1"="2:1"Width: height =2:1If you write at this time"w,2:1"Represents height: width =2:1;Copy the code
<? 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"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <ImageView
       android:id="@+id/img1"
       android:layout_width="100dp"
       android:layout_height="0dp"
       android:scaleType="fitXY"
       android:src="@mipmap/ic_launcher"
       app:layout_constraintDimensionRatio="w,2:1"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

   <ImageView
       android:id="@+id/img2"
       android:layout_width="100dp"
       android:layout_height="0dp"
       android:layout_marginTop="50dp"
       android:scaleType="fitXY"
       android:src="@mipmap/ic_launcher"
       app:layout_constraintDimensionRatio="h,2:1"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/img1" />


</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

  • Case 3:
W: 0DP H: 0DP By default, w is used as the standard to constrain H."h,2:1"Indicates that the height is computed and the width is constrained"w,2:1"The addition of W means that the width is calculated and the height is constrainedCopy the code
<? 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">
    

    <ImageView
        android:id="@+id/img3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintDimensionRatio="w,2:1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

<? 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">


    <ImageView
        android:id="@+id/img3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintDimensionRatio="h,2:1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Width ratio between controls

ConstraintLayout also sets the layout_weight property for its child controls, just like the LinearLayout does, so the width ratio between the child controls is as follows: Layout_constraintHorizontal_weight and layout_constraintVertical_weight

<? 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/view1"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:background="@color/design_default_color_primary_dark"
        app:layout_constraintEnd_toStartOf="@+id/view2"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/view2"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:background="@color/design_default_color_secondary_variant"
        app:layout_constraintEnd_toStartOf="@+id/view3"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@+id/view1"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/view3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/design_default_color_error"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="2"
        app:layout_constraintVertical_weight="1"
        app:layout_constraintStart_toEndOf="@+id/view2"
        app:layout_constraintBottom_toTopOf="@+id/view4"
        app:layout_constraintTop_toTopOf="parent" />
    <View
        android:id="@+id/view4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/teal_200"
        app:layout_constraintEnd_toEndOf="@+id/view3"
        app:layout_constraintStart_toStartOf="@+id/view3"
        app:layout_constraintVertical_weight="1"
        app:layout_constraintBottom_toTopOf="@+id/view5"
        app:layout_constraintTop_toBottomOf="@+id/view3" />
    <View
        android:id="@+id/view5"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/purple_200"
        app:layout_constraintVertical_weight="1"
        app:layout_constraintEnd_toEndOf="@+id/view3"
        app:layout_constraintStart_toStartOf="@+id/view3"
        app:layout_constraintTop_toBottomOf="@+id/view4"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Dimensions

When the width or height of the control is set to 0dp, you can specify the width or height of the control as a percentage of the space of the parent control with two properties ranging from 0 to 1

    1. layout_constraintWidth_percent
    1. layout_constraintHeight_percent
<? 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn_target"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:text="Target Button"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Source Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent="0.3" />


</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Visibility

In any other layout, if the View’s visibility property is set to GONE, all other properties that rely on the View to reference and position will be invalidated, and will be different in ConstraintLayout

<? 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#f5ec7e"
        android:gravity="center"
        android:text="Hello World!"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#fa6e61"
        android:gravity="center"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="@+id/tv1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/tv1"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

If the yellow cube’s visibility property is set to GONE, the position of the red cube will change. This can be interpreted as the yellow square shrinking to an invisible dot in the middle of its original position, while the red square is changed to be positioned according to that dot

<? 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#f5ec7e"
        android:gravity="center"
        android:text="Hello World!"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#fa6e61"
        android:gravity="center"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="@+id/tv1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/tv1"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

In addition, the red square can also rely on the following properties to control the margin value of the red square when the yellow square is Gone. These properties will only take effect when the visibility property of the yellow square is set to Gone

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

Circular positioning

Circular positioning is used to position two views in two dimensions, Angle and distance, with the center of two views as the anchor point

  1. App :layout_constraintCircle – ID of the target View
  2. App :layout_constraintCircleAngle – Aligned Angle
  3. App :layout_constraintCircleRadius – Distance from target View (clockwise, 0~360 degrees)

<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:ignore="MissingConstraints"
    android:id="@+id/root">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/sun"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@drawable/sun"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/earth"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/earth"
        app:layout_constraintCircleAngle="45"
        app:layout_constraintCircleRadius="150dp"
        app:layout_constraintCircle="@id/sun"
            />


    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/moon"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:src="@drawable/moon"
        app:layout_constraintCircleRadius="40dp"
        app:layout_constraintCircleAngle="270"
        app:layout_constraintCircle="@id/earth" />
    
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Guideline

Guideline is a subclass of View, used in the same way as regular views, but with the following special properties:

  • Width and height are 0
  • The visibility is view.gone

The indicator line is meant to help other views locate and does not actually appear on the page

For example, the following code adds two guidelines, and you can choose to set the location of the Guideline using percentage or actual distance, and set the orientation of the Guideline using the orientation property

<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="120dp"
        app:layout_constraintGuide_end="60dp"  />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        app:layout_constraintGuide_percent="0.5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" />
    <TextView
        android:id="@+id/tv_username"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:layout_marginTop="72dp"
        android:gravity="center_vertical"
        android:text="Username"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_password"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:gravity="center_vertical"
        android:text="Password"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintTop_toBottomOf="@+id/tv_username" />

    <EditText
        android:id="@+id/et_username"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="@+id/tv_username"
        app:layout_constraintStart_toStartOf="@+id/guideline" />

    <EditText
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="@+id/tv_password"
        app:layout_constraintStart_toEndOf="@+id/tv_password" />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:background="#f5ec7e"
        android:gravity="center"
        android:text="Hello World!"
        app:layout_constraintLeft_toRightOf="@+id/guideline"
        app:layout_constraintTop_toBottomOf="@+id/guideline2" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Barrier

Many times the width and height of a control changes according to the amount of data it contains. It is difficult to set the relationship between controls when you have multiple controls that are bound by each other. Barrier, like GuideLine, is a virtual View that is not visible to the interface and is used as an aid to layout

Barrier can use the following properties:

    1. BarrierDirection: sets the location of the Barrier. The values are bottom, top, start, end, left, and right
    1. Constraint_referenced_ids: Specifies the ID of the control referenced by the Barrier
    1. BarrierAllowsGoneWidgets: Defaults to true and creates a Barrier where the control referred to by the Barrier has already been resolved. If set to false, the Gone control is not taken into account
<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="end"
        app:constraint_referenced_ids="view1,view2" />


    <TextView
        android:id="@+id/view1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Long text long text long text"
        android:textSize="32sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/view2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="52dp"
        android:text="Long"
        android:textSize="32sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view1" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toEndOf="@id/barrier"
        app:layout_constraintTop_toTopOf="@+id/view1" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toStartOf="@+id/barrier"
        app:layout_constraintTop_toTopOf="@+id/view2" />
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Group

In redevelopment, we often encounter such a requirement: in a certain case, we need to set the show and hide of N Spaces under certain conditions, and the Group can meet this requirement.

<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.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">

    <Button
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/button"
        android:text="group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <androidx.constraintlayout.widget.Group
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/view1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toEndOf="@+id/view1"
        app:layout_constraintTop_toTopOf="@+id/view1" />

    <ImageView
        android:id="@+id/view7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="80dp"
        android:layout_marginTop="72dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toEndOf="@+id/view1"
        app:layout_constraintTop_toTopOf="@+id/view1"
        tools:ignore="RtlCompat" />

    <ImageView
        android:id="@+id/view8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="72dp"
        android:src="@mipmap/ic_launcher"
        tools:ignore="RtlCompat"
        app:layout_constraintStart_toEndOf="@+id/view1"
        app:layout_constraintTop_toTopOf="@+id/view1" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
/ * * *@DescriptionConstraint_referenced_ids: Group controls the visibility of multiple controls, constraint_referenced_ids binds other views, and then indirectly changes the visibility of a bound View by controlling the visibility of the Group separately@Author:         zhangchun
 * @CreateDate:     2021/8/23
 * @Version: 1.0 * /
class Group : AppCompatActivity(a){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_group)
        findViewById<Button>(R.id.button).setOnClickListener {
            findViewById<Group>(R.id.group).visibility = View.GONE
        }
    }
}
Copy the code

Placeholder

Placeholder (Placeholder) Placeholder is associated with a view, which is converted to the specified view by the setContentId() method. That is, the view will be displayed in the Placeholder position, and will disappear from its original position if the view is already in the layout

<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.Placeholder
        android:id="@+id/placeholder"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_width="48dp"
        android:layout_height="48dp" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/favorite"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:onClick="onClick"
        android:src="@drawable/ic_favorite_black_24dp"
        android:tint="#E64A19"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/mail"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/mail"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:onClick="onClick"
        android:src="@drawable/ic_mail_black_24dp"
        android:tint="#512DA8"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/save"
        app:layout_constraintStart_toEndOf="@id/favorite"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/save"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:onClick="onClick"
        android:src="@drawable/ic_save_black_24dp"
        android:tint="#D32F2F"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/play"
        app:layout_constraintStart_toEndOf="@id/mail"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/play"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:onClick="onClick"
        android:src="@drawable/ic_play_circle_filled_black_24dp"
        android:tint="#FFA000"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/save"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
class PlaceHolder : AppCompatActivity(a){

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_place_holder)
    }

    fun onClick(view: View) {
        findViewById<Placeholder>(R.id.placeholder).setContentId(view.id)
    }
}
Copy the code

Chains

Multiple controls constrain each other’s positions through explicit mutual constraints, thus forming a chain.

Chains are divided into horizontal chains and vertical chains, which are set with layout_constraintHorizontal_chainStyle and layout_constraintVertical_chainStyle respectively. The attribute values are as follows:

  • Spread (default)
  • spread_inside
  • packed
<? 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">

    <ImageView
        android:id="@+id/avatar"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toTopOf="@+id/textview"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed"></ImageView>

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="200dp"
        android:background="@color/design_default_color_secondary_variant"
        android:text="Long text long text long text long text long text long text long text long text"
        android:textColor="@android:color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="@+id/avatar"
        app:layout_constraintStart_toStartOf="@+id/avatar"
        app:layout_constraintTop_toBottomOf="@+id/avatar" />

    <ImageView
        android:id="@+id/view1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/view2"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toStartOf="parent" />

    <ImageView
        android:id="@+id/view2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/view3"
        app:layout_constraintStart_toEndOf="@+id/view1" />

    <ImageView
        android:id="@+id/view3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/view2" />
    
    <ImageView
        android:id="@+id/view4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:scaleType="fitXY"
        app:layout_constraintBottom_toTopOf="@+id/view1"
        android:layout_marginBottom="20dp"
        app:layout_constraintEnd_toStartOf="@+id/view5"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toStartOf="parent" />

    <ImageView
        android:id="@+id/view5"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:scaleType="fitXY"
        android:layout_marginBottom="20dp"
        app:layout_constraintBottom_toTopOf="@+id/view1"
        app:layout_constraintEnd_toStartOf="@+id/view6"
        app:layout_constraintStart_toEndOf="@+id/view4" />

    <ImageView
        android:id="@+id/view6"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:scaleType="fitXY"
        android:layout_marginBottom="20dp"
        app:layout_constraintBottom_toTopOf="@+id/view1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/view5" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Flow

Flow is a new virtual layout designed to create chained typography that automatically wraps lines or even extends to another area of the screen when space is scarce. Flow is useful when you need to chain layout multiple elements, but are not sure of the actual size of the layout space at run time. You can use Flow to allow the layout to dynamically adapt to changes in the screen size of the application, such as screen width changes as the device rotates.

One of the most important configuration options in Flow is wrapMode, which determines the layout behavior in case of overflow (or line breaks). There are three modes:

  • None – All referenced views are laid out in a chain, and if the content overflows, the overflow content is not visible
  • Chain – When an overflow occurs, the spilled content is wrapped in a new chain layout
  • Aligned-is similar to chain but is arranged in columns rather than rows

<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.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">

    <androidx.constraintlayout.helper.widget.Flow
        android:id="@+id/flow"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@color/design_default_color_primary_variant"
        android:orientation="horizontal"
        app:flow_wrapMode="chain"
        app:flow_verticalGap="16dp"
        app:flow_horizontalGap="16dp"
        app:constraint_referenced_ids="view1,view2,view3,view4,view5,view6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:ignore="RtlCompat" />


    <View
        android:id="@+id/view1"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:background="@color/design_default_color_secondary_variant" />

    <View
        android:id="@+id/view2"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:background="@color/design_default_color_secondary_variant" />

    <View
        android:id="@+id/view3"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_margin="8dp"
        android:background="@color/design_default_color_secondary_variant" />

    <View
        android:id="@+id/view4"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:background="@color/design_default_color_secondary_variant" />

    <View
        android:id="@+id/view5"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:background="@color/design_default_color_secondary_variant" />

    <View
        android:id="@+id/view6"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:background="@color/design_default_color_secondary_variant" />
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
  • none

The following configuration items can be used simultaneously in this mode:

  • Flow_horizontalStyle = “spread | spread_inside | the packed” / / Chains chain form of show
  • flow_verticalStyle = “spread|spread_inside|packed”
  • flow_horizontalBias = “float“// This controls the horizontal offset of the control only when style is packed
  • flow_verticalBias = “float
  • flow_horizontalGap = “dimension“// Sets the left and right spacing for each control
  • flow_verticalGap = “dimension
  • flow_horizontalAlign = “start|end”
  • flow_verticalAlign = “top|bottom|center|baseline

  • chain

The following configuration items can be used simultaneously in this mode:

  • Flow_firstHorizontalStyle = “spread | spread_inside | the packed” / / the first row Chains chain form of show
  • flow_firstVerticalStyle = “spread|spread_inside|packed”
  • flow_firstHorizontalBias = “float“// This controls the horizontal offset of the first row only when style is packed
  • flow_firstVerticalBias = “float
  • Flow_lastHorizontalStyle = “spread | spread_inside | the packed” / / the last row Chains chain form of show
  • flow_lastHorizontalBias = “float

  • aligned

Layer

If you want to rotate, translate, or scale multiple views as a whole, Layer is the best choice

<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <Button
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/button"
        android:text="layer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>



    <androidx.constraintlayout.helper.widget.Layer
        android:id="@+id/layer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="view,view1,view7,view8"
        tools:ignore="MissingConstraints" />


    <ImageView
        android:id="@+id/view1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toEndOf="@+id/view1"
        app:layout_constraintTop_toTopOf="@+id/view1" />

    <ImageView
        android:id="@+id/view7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="80dp"
        android:layout_marginTop="72dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toEndOf="@+id/view1"
        app:layout_constraintTop_toTopOf="@+id/view1" />

    <ImageView
        android:id="@+id/view8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="72dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintStart_toEndOf="@+id/view1"
        app:layout_constraintTop_toTopOf="@+id/view1" />
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
class LayerActivity : AppCompatActivity(a){
    override fun setContentView(view: View?) {
        setContentView(R.layout.activity_layer)
        findViewById<Button>(R.id.button).setOnClickListener {
            findViewById<Layer>(R.id.layer).rotation = 45f
            findViewById<Layer>(R.id.layer).translationY = 100f
            findViewById<Layer>(R.id.layer).translationX = 100f}}}Copy the code

ConstraintSet

Layer animates part of ConstraintLayout, and ConstraintSet animates the entire ConstraintLayout

ConstraintSet can be understood as a collection of constraint rules for all of ConstraintLayout’s child controls. ConstraintLayout is used to smoothly change the position of all the child controls within ConstraintLayout, which requires a major adjustment depending on the interaction rules

  • activity_constraint_start
<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:onClick="onClick">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/twitter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:src="@drawable/twitter"
        android:tint="#00ACED"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/wechat"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/wechat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/wechat"
        android:tint="#51C332"
        app:layout_constraintEnd_toStartOf="@+id/weibo"
        app:layout_constraintStart_toEndOf="@+id/twitter"
        app:layout_constraintTop_toTopOf="@+id/twitter" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/weibo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/weibo"
        android:tint="#D32024"
        app:layout_constraintEnd_toStartOf="@+id/qzone"
        app:layout_constraintStart_toEndOf="@+id/wechat"
        app:layout_constraintTop_toTopOf="@+id/wechat" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/qzone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/qzone"
        android:tint="#FFCE00"

        app:layout_constraintEnd_toStartOf="@+id/wechat_friend"
        app:layout_constraintStart_toEndOf="@+id/weibo"
        app:layout_constraintTop_toTopOf="@+id/weibo" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/wechat_friend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/wechat_friend"
        android:tint="#51C332"
        app:layout_constraintEnd_toStartOf="@+id/qq"
        app:layout_constraintStart_toEndOf="@+id/qzone"
        app:layout_constraintTop_toTopOf="@+id/qzone" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/qq"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/qq"
        android:tint="#00ACED"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/wechat_friend"
        app:layout_constraintTop_toTopOf="@+id/wechat_friend" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
  • activity_constraint_end
<? xml version="1.0" encoding="utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/twitter"
        android:onClick="onClick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:src="@drawable/twitter"
        android:tint="#00ACED"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/wechat"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/wechat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/wechat"
        android:tint="#51C332"
        app:layout_constraintEnd_toStartOf="@+id/weibo"
        app:layout_constraintStart_toEndOf="@+id/twitter"
        app:layout_constraintTop_toTopOf="@+id/twitter" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/weibo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/weibo"
        android:tint="#D32024"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/wechat"
        app:layout_constraintTop_toTopOf="@+id/wechat" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/qzone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:src="@drawable/qzone"
        android:tint="#FFCE00"
        app:layout_constraintEnd_toStartOf="@+id/wechat_friend"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/twitter" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/wechat_friend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/wechat_friend"
        android:tint="#51C332"
        app:layout_constraintEnd_toStartOf="@+id/qq"
        app:layout_constraintStart_toEndOf="@+id/qzone"
        app:layout_constraintTop_toTopOf="@+id/qzone" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/qq"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/qq"
        android:tint="#00ACED"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/wechat_friend"
        app:layout_constraintTop_toTopOf="@+id/wechat_friend" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
class ConstraintSetX : AppCompatActivity(a){

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_constraint_start)
    }


    @RequiresApi(Build.VERSION_CODES.KITKAT)
    fun onClick(view: View) {
        val constraintLayout = view as ConstraintLayout

        val constraintSet = ConstraintSet().apply {
            isForceId = false
            clone(this@ConstraintSetX,
                R.layout.activity_constraint_end
            )
        }
        TransitionManager.beginDelayedTransition(constraintLayout)
        constraintSet.applyTo(constraintLayout)
    }
Copy the code

ImageFilterView

ImageFilterView is a View placed in the utils.widget package of ConstraintLayout. From the package name, we can guess that ImageFilterView is an additional tool attribute class provided by Google. ConstraintLayout has nothing to do with ConstraintLayout itself.

ImageFilterView directly inherits from AppCompatImageView, which extends many functions for implementing graphics transformation

attribute meaning
altSrc Used to specify the target image to be converted from SRC. You can use the crossfade to fade in and out
crossfade Sets the degree of blending between SRC and altSrc images. 0 = SRC = 1 altSrc images
saturation Saturation. 0= gray scale, 1= original, 2= supersaturated
brightness Brightness. 0= black, 1= raw, 2= double brightness
warmth Color temperature. 1= natural, 2= warm, 0.5= cool
contrast Contrast. 1= constant, 0= gray, 2= high contrast
round Used to implement rounded corners, with dimension as the value
roundPercent The value ranges from 0F to 1f. If the value is 1F, a circular picture will be formed
<? 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">

    <androidx.constraintlayout.helper.widget.Flow
        android:id="@+id/flow"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:flow_wrapMode="aligned"
        app:flow_verticalGap="16dp"
        app:flow_horizontalGap="16dp"
        app:constraint_referenced_ids="imageView1,imageView2,imageView3,imageView4,imageView5,imageView6,imageView7"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:ignore="RtlCompat" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/imageView1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintEnd_toStartOf="@id/imageView2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/avator" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/imageView2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintEnd_toStartOf="@id/imageView3"
        app:layout_constraintStart_toEndOf="@+id/imageView1"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/avator" />


    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/imageView3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintEnd_toStartOf="@id/imageView4"
        app:layout_constraintStart_toEndOf="@+id/imageView2"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/avator" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/imageView4"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintEnd_toStartOf="@id/imageView5"
        app:layout_constraintStart_toEndOf="@+id/imageView3"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/avator" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/imageView5"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintEnd_toStartOf="@id/imageView6"
        app:layout_constraintStart_toEndOf="@+id/imageView4"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/avator" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/imageView6"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintEnd_toStartOf="@id/imageView7"
        app:layout_constraintStart_toEndOf="@+id/imageView5"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/avator" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/imageView7"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintStart_toEndOf="@+id/imageView6"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/avator" />


    <androidx.appcompat.widget.AppCompatSeekBar
        android:id="@+id/seekBar"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:max="100"
        android:progress="0"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
class ImageFilerActivity : AppCompatActivity(a){
    var imageView1 : ImageFilterView? =null
    var imageView2 : ImageFilterView? =null
    var imageView3 : ImageFilterView? =null
    var imageView4 : ImageFilterView? =null
    var imageView5 : ImageFilterView? =null
    var imageView6 : ImageFilterView? =null
    var imageView7 : ImageFilterView? =null
    var seekBar : AppCompatSeekBar? =null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState) setContentView(R.layout.activity_imagefilter) imageView1=findViewById(R.id.imageView1) imageView2=findViewById(R.id.imageView2) imageView3=findViewById(R.id.imageView3) imageView4=findViewById(R.id.imageView4) imageView5=findViewById(R.id.imageView5) imageView6=findViewById(R.id.imageView6) imageView7=findViewById(R.id.imageView7) seekBar=findViewById(R.id.seekBar) seekBar? .setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                if (fromUser) {
                    val realProgress = (progress / 100.0).toFloat() imageView1? .saturation = realProgress *20imageView2? .brightness =1- realProgress imageView3? .warmth = realProgress *20imageView4? .contrast = realProgress *2imageView5? .round = realProgress *40imageView6? .roundPercent = realProgress imageView7? .crossfade = realProgress } }override fun onStartTrackingTouch(seekBar: SeekBar?) {}override fun onStopTrackingTouch(seekBar: SeekBar?) {}})}}Copy the code

Blog.csdn.net/shulianghan… Developer. The android. Google. Cn/reference/a… Juejin. Cn/post / 690521… Juejin. Cn/post / 691171…