A year ago, write ConstraintLayout. Is reading just one paragraph really enough? The article said that any technology will have a time limit, only continuous learning, continuous renewal of self, will not outer. Have a friend also message, hope to update… That’s where this article comes in.
For now, there are only some new features and new gameplay in 2.0, which is not intended to replace 1.x, so 1.x will have to be learned. Good article recommended 2.0 new content in the practice of development is also very practical, suggestions can get on the car.
“Through ignorance and inertia, we feel we are touching the ceiling of technology“
“If it works for you, give it a thumbs up“
ConstraintLayout has been updated to 2.0.0-beta8, so add a dependent pose:
AndroidX:
implementation 'androidx. Constraintlayout: constraintlayout: 2.0.0 - beta8'
Copy the code
Support library:
implementation 'com. Android. Support. The constraint, the constraint - layout: 2.0.0 - beta8'
Copy the code
Version notes:
Alpha: A buggy internal beta
Beta: Public beta with fewer bugs and early adopters
Rc: release candidate, with the same features as the release, with minor bugs fixed;
Stable: You can use it if you want. It’s a blessing to find a bug.
1. Flow Virtual Layout (Alpha 5 added)
Normally, the list display is generally implemented by the ListView or RecyclerView, but the sub-item layout is very rigid. Imagine if the details page of a work ended with a bunch of tabs that looked like this.
This layout usesFlow
To achieve special simplicity and convenience, and throughflow_wrapMode
Property allows you to set different alignments.
Here is a simple example of layout code: Constraint_referenced_ids the Flow layout is associated with constraint_referenced_IDS, which is the id of the View to be constrained. The Flow layout is associated with constraint_referenced_IDS, which is the id of the View to be constrained. Add tools to ConstraintLayout :ignore=”MissingConstraints”
The flow_horizontalGap attribute of the Flow layout represents the horizontal interval between two views, and the flow_verticalGap is the vertical interval.
<? 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:ignore="MissingConstraints"// Ignore the Android Studio 4.0 red alert tools:context=".MainActivity"> <androidx.constraintlayout.helper.widget.Flow android:id="@+id/flow" android:layout_width="wrap_content" android:layout_height="wrap_content" app:constraint_referenced_ids="tvA,tvB,tvC,tvD,tvE,tvF,tvG" app:flow_horizontalGap="30dp"//View horizontal spacing app:flow_verticalGap="30dp"// Vertical spacing app:flow_wrapMode="none" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/tvA" android:layout_width="50dp" android:layout_height="50dp" android:background="@color/colorPrimary" android:gravity="center" android:text="A" android:textColor="#ffffff" android:textSize="16sp" /> <TextView android:id="@+id/tvB" android:layout_width="50dp" android:layout_height="50dp" android:background="@color/colorPrimary" android:gravity="center" android:text="B" android:textColor="#ffffff" android:textSize="16sp" /> <TextView android:id="@+id/tvC" android:layout_width="50dp" android:layout_height="50dp" android:background="@color/colorPrimary" android:gravity="center" android:text="C" android:textColor="#ffffff" android:textSize="16sp" /> <TextView android:id="@+id/tvD" android:layout_width="50dp" android:layout_height="50dp" android:background="@color/colorPrimary" android:gravity="center" android:text="D" android:textColor="#ffffff" android:textSize="16sp" /> <TextView android:id="@+id/tvE" android:layout_width="50dp" android:layout_height="50dp" android:background="@color/colorPrimary" android:gravity="center" android:text="E" android:textColor="#ffffff" android:textSize="16sp" /> <TextView android:id="@+id/tvF" android:layout_width="50dp" android:layout_height="50dp" android:background="@color/colorPrimary" android:gravity="center" android:text="F" android:textColor="#ffffff" android:textSize="16sp" /> <TextView android:id="@+id/tvG" android:layout_width="50dp" android:layout_height="50dp" android:background="@color/colorPrimary" android:gravity="center" android:text="G" android:textColor="#ffffff" android:textSize="16sp" /> </androidx.constraintlayout.widget.ConstraintLayout> Copy the code
There are three different values for the flow_wrapMode attribute. Based on the layout above, change the values to see the effect:
“None value” : All referenced views form a chain, centered horizontally, and views beyond the sides of the screen are not visible.
“Chian value” : the referenced views form a chain, the excess views are wrapped, and the views in the same row are bisexited.
Aligned values: Referenced views form a chain, but they are aligned in the same column.
Even if it is a chain, you can be constrained by the style of the chain.
Chain constraint
When the flow_wrapMode attribute is aligned and chian, the constraint is carried out by chain. ConstraintLayout, is reading just one paragraph really enough? This article talks about Chain constraints.
Add the following attributes to the Flow layout for different chain constraints:
flow_firstHorizontalStyle
The first horizontal chain is constrained. When there are multiple chains (multiple rows), only the first chain (first row) is constrained, and other chains (other rows) are not constrained.flow_lastHorizontalStyle
The last horizontal chain is constrained. When there are multiple chains (multiple rows), only the last chain (the last row) is constrained. Other chains (other rows) are not constrained.flow_horizontalStyle
Constrain all horizontal chains;flow_firstVerticalStyle
Same level constraint;flow_lastVerticalStyle
Same level constraint;flow_verticalStyle
Constrain all vertical chains;
The value can be spread, spread_inside, or Packed
“Effect:“
“Spread value:
“
Code:
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/flow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
app:constraint_referenced_ids="tvA,tvB,tvC,tvD,tvE,tvF,tvG" app:flow_maxElementsWrap="4" app:flow_horizontalGap="30dp" app:flow_verticalGap="30dp" app:flow_wrapMode="chain" app:flow_horizontalStyle="spread" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> Copy the code
“Spread_inside value:
“
Code:
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/flow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
app:constraint_referenced_ids="tvA,tvB,tvC,tvD,tvE,tvF,tvG" app:flow_maxElementsWrap="4" app:flow_horizontalGap="30dp" app:flow_verticalGap="30dp" app:flow_wrapMode="chain" app:flow_horizontalStyle="spread_inside" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> Copy the code
“The packed value:
“
Code:
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/flow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
app:constraint_referenced_ids="tvA,tvB,tvC,tvD,tvE,tvF,tvG" app:flow_maxElementsWrap="4" app:flow_horizontalGap="30dp" app:flow_verticalGap="30dp" app:flow_wrapMode="chain" app:flow_horizontalStyle="packed" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> Copy the code
Other effects you can try to see the effect in practice, suggest “like” collection of this article, in use will not be able to browse, efficiency is twice the result with half the effort, so as not to waste time Google search.
alignment
In the XML layout above, all TextViews have the same width and height, so they look neat. When the width and height are different, they can be aligned. I tried the aligned app:flow_wrapMode=”aligned”. It didn’t work. It probably has a default value. Consider the case where the flow_wrapMode attribute is None and chain.
Add the following attributes to the Flow layout for different Align constraints:
flow_verticalAlign
The value can be:top
,bottom
,center
,baseline
;flow_horizontalAlign
Align horizontally. The value can be:start
,end
,center
;
The alignment direction is usually opposite to the direction of the chain. For example, the vertical chain style usually aligns the left and right sides and the center of the View.
A simple example: vertical top alignment.
“Effect:“
You can seeE
andG
,F
Align the top.
Code:
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/flow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
app:constraint_referenced_ids="tvA,tvB,tvC,tvD,tvE,tvF,tvG" app:flow_maxElementsWrap="4" app:flow_horizontalGap="30dp" app:flow_verticalGap="30dp" app:flow_wrapMode="chain" app:flow_verticalAlign="top" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> Copy the code
Aligned and Chian are custom versions of None, customizable by adding different attributes. Since Flow is a virtual layout, simply understood as a constraint assistant, it does not add to the layout hierarchy, but can be used just like a normal layout.
“Other attributes“
The XML layout above does not set the Flow to organize the View horizontally or vertically. You can use the orientation attribute to set horizontal and vertical, for example, to vertical.
When the flow_wrapMode attribute is aligned and chian, the maximum number of subviews per row is controlled by the flow_maxElementsWrap attribute. For example, flow_maxElementsWrap=3.
When the flow_wrapMode attribute is none, A and G are blocked from view.
To make A or G visible, go through the Settingsflow_horizontalBias
Property, the value is0-1
In between. The precondition is thatflow_horizontalStyle
Properties forpacked
It takes effect.
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/flow"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="tvA,tvB,tvC,tvD,tvE,tvF,tvG" app:flow_horizontalGap="30dp" app:flow_verticalGap="30dp" app:flow_wrapMode="none" app:flow_horizontalStyle="packed" app:flow_horizontalBias="0" android:layout_marginTop="10dp" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> Copy the code
“Effect:“ Set up theflow_horizontalBias=1
Then you can see the G. There are other properties like ChainStyle that you can play with. Or, of course, in theflow_wrapMode
Property takes effect for other values.
There are many different effects that can be combined with different properties, and the MotionLayout animation makes it even cooler.
2. Layer layout
Layer is also a ConstraintHelper. It is simpler than Flow and is often used to add background, or to animate together. Since ConstraintHelper itself inherits from a View, it is no different from adding a common background to multiple views within a ConstraintLayout using a View, only more convenient.
“1. Add background“
Add a common background to the ImageView and TextView:
“Effect:“
“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"> <androidx.constraintlayout.helper.widget.Layer android:id="@+id/layer" android:layout_marginTop="50dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/colorPrimary" app:constraint_referenced_ids="ivImage,tvName" app:layout_constraintLeft_toLeftOf="@id/ivImage" app:layout_constraintRight_toRightOf="parent" android:padding="10dp" app:layout_constraintTop_toTopOf="parent" tools:ignore="MissingConstraints" /> <ImageView android:id="@+id/ivImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:src="@mipmap/ic_launcher_round" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/layer" /> <TextView android:id="@+id/tvName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="New Little Dream" android:textColor="#FFFFFF" android:paddingTop="5dp" app:layout_constraintLeft_toLeftOf="@id/ivImage" app:layout_constraintRight_toRightOf="@id/ivImage" app:layout_constraintTop_toBottomOf="@id/ivImage" /> </androidx.constraintlayout.widget.ConstraintLayout> Copy the code
“2. Joint animation“
Add animation effects to ImageView and TextView via property animation.
“Effect:“
“Code:“
val animator = ValueAnimator.ofFloat( 0f, 360f)
animator.repeatMode=ValueAnimator.RESTART
animator.duration=2000
animator.interpolator=LinearInterpolator()
animator.repeatCount=ValueAnimator.INFINITE
animator.addUpdateListener { layer.rotation= it.animatedValue as Float } layer.setOnClickListener { animator.start() } Copy the code
For those who are fuzzy about attribute animation, you can see: Android Attribute Animation
Support: rotation, displacement, zoom animation. Try the transparency effect on the View itself, not on the constraint View.
Define ConstraintHelper
Flow and Layer are both subclasses of ConstraintHelper. When they do not meet the requirements, they can inherit from ConstraintHelper to implement the desired constraint effect.
There’s an animated AD like this on an APP:
ConstraintHelper is simple enough:
class AdHelper :
ConstraintHelper {
constructor(context: Context?) : super(context)
constructor(context: Context? ,attributeSet: AttributeSet):super(context,attributeSet) constructor(context: Context? ,attributeSet: AttributeSet,defStyleAttr: Int):super(context,attributeSet,defStyleAttr) override fun updatePostLayout(container: ConstraintLayout?) { super.updatePostLayout(container) val views = getViews(container) views.forEach { val anim = ViewAnimationUtils.createCircularReveal(it, 0, 0, 0f, it.width.toFloat()) anim.duration = 5000 anim.start() } } } Copy the code
Layout reference AdHleper:
<? 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">
<com.example.constraint.AdHelper android:layout_width="wrap_content" android:layout_height="wrap_content" app:constraint_referenced_ids="ivLogo" app:layout_constraintLeft_toLeftOf="@id/ivLogo" app:layout_constraintRight_toRightOf="@id/ivLogo" app:layout_constraintTop_toTopOf="@id/ivLogo" /> <ImageView android:id="@+id/ivLogo" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:adjustViewBounds="true" android:scaleType="fitXY" android:src="@mipmap/ic_logo" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> Copy the code
Four, ImageFilterButton
Round picture, round picture how to achieve? The custom View? So ImageFilterButton, one property; ImageFilterButto can do much more.
See how to achieve rounded corners or round images:
“The original:“
将roundPercent
Property set to1
, the values in the0-1
From a square to a circle.
<androidx.constraintlayout.utils.widget.ImageFilterButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
app:roundPercent="1"
android:src="@mipmap/ic_launcher" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> Copy the code
“Effect:“
It can also be setround
Property to implement:
<androidx.constraintlayout.utils.widget.ImageFilterButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:round="50dp" /> Copy the code
“Other attributes:“
The altSrc and SRC attributes are the same concept. Resources provided by altSrc will be cross-faded with resources provided by SRC via the Crossfade attribute. By default,crossfade=0 and the resource referenced by altSrc is invisible, with a value of 0-1. Such as:
<androidx.constraintlayout.utils.widget.ImageFilterButton
android:id="@+id/ivImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:src="@mipmap/ic_launcher" app:altSrc="@mipmap/ic_sun" app:crossfade="0.5" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:round="50dp" /> Copy the code
Crossfade =0.5
Crossfade =1
The next few properties are to adjust the image:
Warmth: 1=neutral, 2=warm, 0.5=cold
brightness
Brightness:0 = black, 1 = original, 2 = twice as bright
; This effect is not good texture, we verify;
Saturation: 0 = grayscale gray, 1 = original original, 2 = hyper saturated;
contrast
Contrast:1 = unchanged original, 0 = gray dim, 2 = high contrast
;
The values above are all 0, 1, and 2, but you can take other values and the effect will be different. And then the last property, overlay, which means I don’t know how to use it, I can’t see it, it doesn’t work, so let me know in the comments, okay?
Fifth, ImageFilterView
ImageFilterView has the same properties as ImageFilterButton, but its two parent classes are different, so some operations are different. ImageFilterButton inherits from AppCompatImageButton, which is ImageButtion. And ImageFilterView inherits from ImageView.
Six, MockView
Remember that UI prototype your project manager gave you? Do you want to pay back the project manager? It’s timeMockView
Simple help to build UI interface by diagonal rectangle + label. Such as:
<? 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">
<androidx.constraintlayout.utils.widget.MockView android:id="@+id/first" android:layout_width="100dp" android:layout_height="100dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.constraintlayout.utils.widget.MockView android:id="@+id/second" android:layout_width="100dp" android:layout_height="100dp" app:layout_constraintLeft_toRightOf="@id/first" app:layout_constraintTop_toBottomOf="@id/first" /> </androidx.constraintlayout.widget.ConstraintLayout> Copy the code
“Effect:“
The black in the middle isMockView
theid
. throughMockView
It’s a good idea to build some UI ideas.
Seven, MotionLayout
MitionLayou is mainly used to animate actions. Please refer to my other article: Android MotionLayout Animation: Follow up on ConstraintLayout
Eight, the complement of the margin problem
Those of you who have practiced ConstraintLayout should know that negative margin has no effect on ConstraintLayout. For example, the following layout: TextView B’s layout_marginLeft and layout_marginTop properties will not take effect.
<? 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/vA" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginLeft="30dp" android:layout_marginTop="30dp" android:background="@color/colorPrimary" android:gravity="center" android:text="A" android:textColor="#FFFFFF" android:textSize="20sp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/vB" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginLeft="-30dp" android:layout_marginTop="-30dp" android:background="@color/colorAccent" android:gravity="center" android:text="B" android:textColor="#FFFFFF" android:textSize="20sp" app:layout_constraintLeft_toRightOf="@id/vA" app:layout_constraintTop_toBottomOf="@id/vA" /> </androidx.constraintlayout.widget.ConstraintLayout> Copy the code
“Effect:“ Can be passed by lightweightSpace
To do this indirectly.
<? 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/vA" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginLeft="30dp" android:layout_marginTop="30dp" android:background="@color/colorPrimary" android:gravity="center" android:text="A" android:textColor="#FFFFFF" android:textSize="20sp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Space android:id="@+id/space" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginRight="30dp" android:layout_marginBottom="30dp" app:layout_constraintBottom_toBottomOf="@id/vA" app:layout_constraintRight_toRightOf="@id/vA" /> <TextView android:id="@+id/vB" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginLeft="-30dp" android:layout_marginTop="-30dp" android:background="@color/colorAccent" android:gravity="center" android:text="B" android:textColor="#FFFFFF" android:textSize="20sp" app:layout_constraintLeft_toRightOf="@id/space" app:layout_constraintTop_toBottomOf="@id/space" /> </androidx.constraintlayout.widget.ConstraintLayout> Copy the code
“Effect:“
ConstraintProperties class is added for updating ConstraintLayout subviews via API (code). Some other can refer to the official documents, the estimate is about the same.
“Reference:“
Official English document
Anyone who can read to the end is great and has good endurance. If this article is useful to you, please “like” it and recommend good ones.
Finally, my personal ability is limited, there are mistakes or mistakes in understanding, I hope you can help to correct, thank you very much.
“Welcome star welcome like” : Github
This article was typeset using MDNICE