史上最全ConstraintLayout使用详解!(建议收藏)
微信改了推动机制,真爱请星标本公号 公众号回复加入BATcoder技术群 BAT
作者:Quyunshuo
https://juejin.cn/user/78820569533070/posts
前言
布局的使用
位置约束
基本方向约束
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity">
<TextView
android:layout_width="100dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
<!-- 基本方向约束 -->
<!-- 我的什么位置在谁的什么位置 -->
app:layout_constraintTop_toTopOf="" 我的顶部和谁的顶部对齐
app:layout_constraintBottom_toBottomOf="" 我的底部和谁的底部对齐
app:layout_constraintLeft_toLeftOf="" 我的左边和谁的左边对齐
app:layout_constraintRight_toRightOf="" 我的右边和谁的右边对齐
app:layout_constraintStart_toStartOf="" 我的开始位置和谁的开始位置对齐
app:layout_constraintEnd_toEndOf="" 我的结束位置和谁的结束位置对齐
app:layout_constraintTop_toBottomOf="" 我的顶部位置在谁的底部位置
app:layout_constraintStart_toEndOf="" 我的开始位置在谁的结束为止
<!-- ...以此类推 -->
-
基线对齐
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="20"
android:textColor="@color/black"
android:textSize="50sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBaseline_toBaselineOf="@id/tv1"
app:layout_constraintStart_toEndOf="@id/tv1" />
</androidx.constraintlayout.widget.ConstraintLayout>
角度约束
app:layout_constraintCircle="" 目标控件id
app:layout_constraintCircleAngle="" 对于目标的角度(0-360)
app:layout_constraintCircleRadius="" 到目标中心的距离
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<ImageView
android:id="@+id/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/android"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/jetpack"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/jetpack"
app:layout_constraintCircle="@+id/android"
app:layout_constraintCircleAngle="45"
app:layout_constraintCircleRadius="70dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
百分比偏移
app:layout_constraintHorizontal_bias="" 水平偏移 取值范围是0-1的小数
app:layout_constraintVertical_bias="" 垂直偏移 取值范围是0-1的小数
注意:在使用百分比偏移时,需要指定对应位置的约束条件
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:layout_width="100dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
控件内边距、外边距、GONE Margin
ConstraintLayout的内边距和外边距的使用方式其实是和其他布局一致的
<!-- 外边距 -->
android:layout_margin="0dp"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="0dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="0dp"
<!-- 内边距 -->
android:padding="0dp"
android:paddingStart="0dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingEnd="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
<!-- GONE Margin -->
app:layout_goneMarginBottom="0dp"
app:layout_goneMarginEnd="0dp"
app:layout_goneMarginLeft="0dp"
app:layout_goneMarginRight="0dp"
app:layout_goneMarginStart="0dp"
app:layout_goneMarginTop="0dp"
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:layout_marginTop="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- 该控件设置了 layout_goneMarginStart="100dp" 当A控件隐藏时才会生效 -->
<TextView
android:id="@+id/B"
android:layout_width="60dp"
android:layout_height="40dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/A"
app:layout_constraintStart_toEndOf="@id/A"
app:layout_constraintTop_toTopOf="@id/A"
app:layout_goneMarginStart="100dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
控件尺寸
尺寸限制
android:minWidth="" 设置view的最小宽度
android:minHeight="" 设置view的最小高度
android:maxWidth="" 设置view的最大宽度
android:maxHeight="" 设置view的最大高度
0dp(MATCH_CONSTRAINT)
app:layout_constraintWidth_default="spread|percent|wrap"
app:layout_constraintHeight_default="spread|percent|wrap"
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginStart="50dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="50dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="spread" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginTop="50dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />
</androidx.constraintlayout.widget.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<!-- 宽度设置为wrap_content -->
<TextView
android:id="@+id/A"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="AAAAAAAAAAAAAAAAAA"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="spread" />
<!-- 宽度设置为0dp wrap模式 -->
<TextView
android:id="@+id/B"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:layout_marginTop="150dp"
android:layout_marginEnd="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="BBBBBBBBBBBBBBBBBBBBBBB"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- 当一个view的宽或高,设置成wrap_content时 -->
app:layout_constrainedWidth="true|false"
app:layout_constrainedHeight="true|false"
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="AAAAAAAAAAAAAAAAAA"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="spread" />
</androidx.constraintlayout.widget.ConstraintLayout>
app:layout_constraintWidth_min="" 0dp下,宽度的最小值
app:layout_constraintHeight_min="" 0dp下,高度的最小值
app:layout_constraintWidth_max="" 0dp下,宽度的最大值
app:layout_constraintHeight_max="" 0dp下,高度的最大值
比例宽高(Ratio)
1. 浮点值,表示宽度和高度之间的比率
2. 宽度:高度,表示宽度和高度之间形式的比率
app:layout_constraintDimensionRatio="" 宽高比例
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Chains(链)
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/B"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/B"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/C"
app:layout_constraintStart_toEndOf="@id/A"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/C"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/B"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/B"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/B"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/C"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/A"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/C"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintStart_toEndOf="@id/B"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Guideline(参考线)
android:orientation="horizontal|vertical" 辅助线的对齐方式
app:layout_constraintGuide_percent="0-1" 距离父级宽度或高度的百分比(小数形式)
app:layout_constraintGuide_begin="" 距离父级起始位置的距离(左侧或顶部)
app:layout_constraintGuide_end="" 距离父级结束位置的距离(右侧或底部)
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/Guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@+id/A"
android:layout_width="120dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/Guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>
GBarrier(屏障)
当我们创建布局时,有时会遇到布局可以根据本地化而更改的情况。这里借助有一个非常简单的例子:
<!-- 用于控制Barrier相对于给定的View的位置 -->
app:barrierDirection="top|bottom|left|right|start|end"
<!-- 取值是要依赖的控件的id,Barrier将会使用ids中最大的一个的宽/高作为自己的位置 -->
app:constraint_referenced_ids="id,id"
<?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/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/warehouse"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="@string/hospital"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="textView2,textView1" />
<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/lorem_ipsum"
app:layout_constraintStart_toEndOf="@+id/barrier7"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Group(组)
app:constraint_referenced_ids="id,id" 加入组的控件id
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginTop="56dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.115"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/B"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginTop="280dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.758"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/C"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginTop="164dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.437"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="A,B,C" />
</androidx.constraintlayout.widget.ConstraintLayout>
Placeholder(占位符)
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="100dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Placeholder
android:layout_width="100dp"
android:layout_height="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Flow(流式虚拟布局)
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/B"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/C"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/D"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="D"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/E"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="E"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:constraint_referenced_ids="A,B,C,D,E"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
链约束
app:flow_horizontalStyle="packed|spread|spread_inside" 所有水平链的配置
app:flow_verticalStyle="packed|spread|spread_inside" 所有垂直链的配置
app:flow_firstHorizontalStyle="packed|spread|spread_inside" 第一条水平链的配置,其他条不生效
app:flow_firstVerticalStyle="packed|spread|spread_inside" 第一条垂直链的配置,其他条不生效
app:flow_lastHorizontalStyle="packed|spread|spread_inside" 最后一条水平链的配置,其他条不生效
app:flow_lastVerticalStyle="packed|spread|spread_inside" 最后一条垂直链的配置,其他条不生效
对齐约束
<!-- top:顶对齐、bottom:底对齐、center:中心对齐、baseline:基线对齐 -->
app:flow_verticalAlign="top|bottom|center|baseline"
<!-- start:开始对齐、end:结尾对齐、center:中心对齐 -->
app:flow_horizontalAlign="start|end|center"
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H,I,J"
app:flow_verticalAlign="top"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H,I,J"
app:flow_verticalAlign="bottom"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H,I,J"
app:flow_verticalAlign="center"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H,I,J"
app:flow_verticalAlign="baseline"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
数量约束
Layer(层布局)
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<androidx.constraintlayout.helper.widget.Layer
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/common_rect_white_100_10"
android:padding="10dp"
app:constraint_referenced_ids="AndroidImg,NameTv" />
<ImageView
android:id="@+id/AndroidImg"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:src="@drawable/android"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/NameTv"
android:layout_width="100dp"
android:layout_height="40dp"
android:gravity="center"
android:text="Android"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@id/AndroidImg"
app:layout_constraintStart_toStartOf="@id/AndroidImg"
app:layout_constraintTop_toBottomOf="@id/AndroidImg" />
</androidx.constraintlayout.widget.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<ImageView
android:id="@+id/AndroidImg"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:src="@drawable/android"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/NameTv"
android:layout_width="100dp"
android:layout_height="40dp"
android:gravity="center"
android:text="Android"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@id/AndroidImg"
app:layout_constraintStart_toStartOf="@id/AndroidImg"
app:layout_constraintTop_toBottomOf="@id/AndroidImg" />
<androidx.constraintlayout.helper.widget.Layer
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/common_rect_white_100_10"
android:padding="10dp"
app:constraint_referenced_ids="AndroidImg,NameTv" />
</androidx.constraintlayout.widget.ConstraintLayout>
ImageFilterButton & ImageFilterView
圆角图片
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<androidx.constraintlayout.utils.widget.ImageFilterView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/mi"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:roundPercent="0.7" />
</androidx.constraintlayout.widget.ConstraintLayout>
图片过滤
MockView
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<androidx.constraintlayout.utils.widget.MockView
android:id="@+id/Avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="80dp"
android:layout_marginTop="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.utils.widget.MockView
android:id="@+id/Name"
android:layout_width="100dp"
android:layout_height="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/Avatar"
app:layout_constraintTop_toTopOf="@id/Avatar" />
<androidx.constraintlayout.utils.widget.MockView
android:id="@+id/Age"
android:layout_width="100dp"
android:layout_height="30dp"
app:layout_constraintBottom_toBottomOf="@id/Avatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/Avatar" />
</androidx.constraintlayout.widget.ConstraintLayout>
ConstraintProperties(流式API)
val properties = ConstraintProperties(findViewById(R.id.image))
properties.translationZ(32f)
.margin(ConstraintSet.START, 43)
.apply()
MotionLayout
结语
参考
新小梦:Constraintlayout 2.0:你们要的更新来了 https://juejin.cn/post/6854573221312725000
谷歌开发者:Constraint Layout 2.0 用法详解 https://zhuanlan.zhihu.com/p/336387890
constraintlayout网站 https://constraintlayout.com/basics/barriers.html
推荐阅读
• 耗时2年,Android进阶三部曲第三部《Android进阶指北》出版!
• 『BATcoder』做了多年安卓还没编译过源码?一个视频带你玩转!
BATcoder技术群,让一部分人先进大厂
大家好,我是刘望舒,腾讯云最具价值专家TVP,著有畅销书《Android进阶之光》《Android进阶解密》《Android进阶指北》,连续四年蝉联电子工业出版社年度优秀作者,谷歌开发者社区特邀讲师。
前华为技术专家,现大厂技术负责人。
想要加入 BATcoder技术群,公号回复BAT
即可。
为了防止失联,欢迎关注我的小号
微信改了推送机制,真爱请星标本公号👇
评论