What do YOU gain from reading this article?

In fact, this article is a cool text, suitable for solving the problem of constraint layout before you know but can not make up your mind to use it in the actual work of readers, read this article you can know how cool constraint layout can be, and then can’t wait to use it.

Sanlian layout

Take a look at this layout. It’s in the headlines. As an item in the list page, and there are three images in the middle of the item, usually when we get the design draft, we find that this type of UI must have a relative layout in the outermost layer, and then we store three images in another linearlayout and use weights to do it. This is simple but adds another layer of layout.

With the constraint layout, this nesting layout situation does not occur

<? 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"> <! -- top--> <TextView android:id="@+id/v1"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@color/colorAccent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"></TextView>

    <TextView
        android:id="@+id/tv1"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#CDCD00"
        android:gravity="center"
        android:text="Figure 1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/tv2"
        app:layout_constraintTop_toBottomOf="@id/v1"></TextView>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#FF7F24"
        android:gravity="center"
        android:text=Figure 2 ""
        app:layout_constraintStart_toEndOf="@id/tv1"
        app:layout_constraintEnd_toStartOf="@id/tv3"
        app:layout_constraintTop_toBottomOf="@id/v1"></TextView>

    <TextView
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#AB82FF"
        android:gravity="center"
        android:text="3"
        android:id="@+id/tv3"
        app:layout_constraintStart_toEndOf="@id/tv2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/v1">
    </TextView>
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Take a look at the effect:

You even said I wanted weight

Just add this property

        app:layout_constraintHorizontal_weight="2"

Copy the code

Center relative to a control

If you look at this layout, it’s actually douyin’s personal center page. The profile picture is a circular one, and the friends in the background are vertically centered in this circular profile picture

What should we do if we don’t have to constrain the layout? I must add a relative layout in the parent layout, and then the height of the relative layout is the same as the height of the avatar icon, and then the rest of the edit profile friends, etc., directly set the vertical center.

That’s fine, but it’s still an extra layer of layout. Layout with constraints is easy

<? 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/tv1"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="30dp"
        android:background="#CDCD00"
        android:gravity="center"
        android:text="Head on the left"
        app:layout_constraintEnd_toStartOf="@id/tv2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></TextView>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="60dp"
        android:layout_height="30dp"
        android:background="#FF7F24"
        android:gravity="center"
        android:text="Edit information"
        android:layout_marginLeft="30dp"
        app:layout_constraintStart_toEndOf="@id/tv1"
        app:layout_constraintBottom_toBottomOf="@id/tv1"
        app:layout_constraintTop_toTopOf="@id/tv1"></TextView>


    <TextView
        android:id="@+id/tv3"
        android:layout_width="60dp"
        android:layout_height="30dp"
        android:background="#00FF7F"
        android:gravity="center"
        android:text="+ friends"
        android:layout_marginLeft="30dp"
        app:layout_constraintStart_toEndOf="@id/tv2"
        app:layout_constraintBottom_toBottomOf="@id/tv1"
        app:layout_constraintTop_toTopOf="@id/tv1"></TextView>


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

Look at the effect

A semipermeable layout

Take a look at the results:

This layout is not uncommon, usually the yellow part is a background, and then the orange part is half deep in the yellow background. The first thing we do when we get this UI design is use a relative layout and set a negative margin.

There is a downside to this, however. In addition to nesting the layout, the negative margin value must be calculated dynamically, because you never know if the actual height of your orange image is fixed. Let’s say there’s a sliding requirement, because the orange part gets smaller as you slide, so you have to keep changing the negative value of this margin, which becomes very troublesome.

All of these problems go away with constrained layouts

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


    <View
        android:id="@+id/tv1"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:background="#CDCD00"
        android:gravity="center"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></View>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="160dp"
        android:layout_height="80dp"
        android:background="#FF7F24"
        android:gravity="center"
        android:text="Half of them are in sibling nodes."
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv1"
        app:layout_constraintBottom_toBottomOf="@id/tv1"></TextView>



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

Baseline alignment versus component alignment

Common component alignment

<? 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"> <! -- top--> <TextView android:id="@+id/v1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="30dp"
        android:gravity="center"
        android:text="Ha ha ha ha."
        android:background="@color/colorAccent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"></TextView>



    <TextView
        android:id="@+id/v2"
        android:layout_width="80dp"
        android:layout_height="50dp"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="30dp"
        android:gravity="center"
        android:text="Component alignment"
        android:background="@color/colorAccent"
        app:layout_constraintLeft_toRightOf="@id/v1"
        app:layout_constraintBottom_toBottomOf="@id/v1"></TextView>

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

It’s also handy to want text baseline alignment

Just add a property

        app:layout_constraintBaseline_toBaselineOf="@id/v1"

Copy the code

Angle positioning

In fact, I think this is only useful if you’re doing complicated custom views especially if you’re dragging. Otherwise it doesn’t really mean much, but once you start animating you’ll find it’s a great Angle to use!

Looking at the diagram first, the position of the control in the upper right is based on the position in the middle. There are three elements

First: the origin of positioning. That’s the center of our TV in the middle of the screen. Number two: the length of this radius, which is the length of our red line in the picture. Number three: The Angle

So let me write that down

<? 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"> <! -- top--> <TextView android:id="@+id/v1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:gravity="center"
        android:text="I'm in the middle of the screen."
        android:background="@color/colorAccent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"></TextView>



    <TextView
        android:id="@+id/v2"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="30dp"
        android:gravity="center"
        android:text="I'm 65 degrees above the center."
        android:background="@color/colorAccent"
        app:layout_constraintCircle="@id/v1"
        app:layout_constraintCircleRadius="180dp"
        app:layout_constraintCircleAngle="65"
      ></TextView>

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

So these are the three main properties

 app:layout_constraintCircle="@id/v1"
        app:layout_constraintCircleRadius="180dp"
        app:layout_constraintCircleAngle="65"
Copy the code

You can imagine if you have a custom view animation or something related to the view trajectory, then in fact, just a property animation to change the radius or Angle, very easy!

Gone does not affect absolute position

Look at a picture like this

It’s easy to do it in a relative layout, so v2 just has to be to the right of v1. But sometimes in the actual business, our V1 may not be displayed or the width will be 0 directly because of some circumstances. And then v2 is going to be shifted to the left.

Relative layout is very cumbersome to deal with. But with constraint layouts, it’s pretty simple

We make the blue one disappear, but the turquoise one stays in place

Take a look at 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"
    tools:context=".MainActivity">



    <View
        android:id="@+id/v1"
        android:visibility="gone"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="30dp"
        android:background="@color/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"></View>

    <View
        android:id="@+id/v2"
        app:layout_goneMarginLeft="130dp"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintLeft_toRightOf="@id/v1"
        app:layout_constraintTop_toTopOf="@id/v1"
        android:background="@color/colorAccent"></View>




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

The important thing is that the app:layout_goneMarginLeft attribute is in play

Multiple views are centered together

Look at this chart

If I don’t have to constrain the layout and I want to center these two views vertically. Then I can only wrap another layer of layout outside.

But if you use constraint layout, it’s easy

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

    <View
        android:id="@+id/v1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/v2"
        app:layout_constraintVertical_chainStyle="packed"

        ></View>

    <View
        android:id="@+id/v2"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="30dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/v1"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="@color/colorAccent"></View>


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

App :layout_constraintVertical_chainStyle

Aspect ratio view

Sometimes we want to give a width and an aspect ratio to dynamically set the height of a view, or height fixed to dynamically set the width. In the past, you had to write your own custom view or dynamic calculation in the code.

The constraint layout is much simpler

 <View
        android:id="@+id/v1"
        android:layout_width="100dp"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="2:5"
        android:background="@color/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        ></View>
Copy the code

Effect:

Note app:layout_constraintDimensionRatio and Android :layout_height=”0dp” should be used together

App :layout_constraintWidth_percent= This is similar to the key attribute of the percentage layout, which I won’t show you

Cut the nested layout with invisible guides

Note that the dotted line is not actually visible; it is only used to aid display in the XML preview. This requirement is easy to see in the actual UI draft login registration, where the username and password are right-aligned. But with constrained layouts, it’s much easier to define an invisible helper line for similar requirements

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


    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.3" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:text="Username"
        android:gravity="right|center_vertical"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        tools:layout_editor_absoluteY="36dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="63dp"
        android:layout_height="80dp"
        android:gravity="right|center_vertical"
        android:text="Password"
        tools:layout_editor_absoluteX="60dp"
        tools:layout_editor_absoluteY="158dp" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPassword"
        app:layout_constraintBottom_toBottomOf="@+id/textView"
        app:layout_constraintTop_toTopOf="@+id/textView"
        app:layout_constraintVertical_bias="0.6"
        tools:layout_editor_absoluteX="123dp" />

    <EditText
        android:id="@+id/editText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPassword"
        tools:layout_editor_absoluteX="123dp"
        tools:layout_editor_absoluteY="169dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

The keyword is androidx. Constraintlayout. Widget. The Guideline

Set the visibility of a set of Views

We already know that constraint layout essentially wants us to reduce hierarchical nesting, but sometimes you might want to have hierarchical nesting to help you achieve visibility of a set of views for example

There are three textViews side by side in the picture and I want to control whether they are displayed together or not. Considering we don’t want to add nested layouts anymore.

So you need to write:

<androidx.constraintlayout.widget.Group android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:visibility="gone"
        app:constraint_referenced_ids="textView3,textView4,textView5"
        >

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

Similarly androidx. Constraintlayout. Widget. The Barrier such as a Helper.