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.