ConstraintLayout 核心用法详解(一):相对定位、边距、偏移与环形定位
ConstraintLayout布局学习1
2016年Google推出了 ConstraintLayout 布局,可以译为“约束布局”,并在 Android Studio 2.3 创建的默认布局中都采用ConstraintLayout 作为最外层布局。
ConstraintLayout 很好的解决了旧布局方式的弊端(LinearLayout、RelativeLayout 等):布局层级多导致UI渲染差、界面卡顿等。
ConstraintLayout 的特点:
- 扁平布局,无嵌套,一个层级就可以绘制复杂布局;
- 渲染性能高;
- 集合了线性布局、相对布局、百分比布局的特点和大多数功能;
- 支持可视化环境下拖拽绘制约束布局。
引入方式(Groovy):
//support包引入
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
//androidx引入
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
引入方式(Kotlin):
implementation("androidx.constraintlayout:constraintlayout:2.2.1")
下面介绍使用 ConstraintLayout 如何绘制布局。
1. 相对定位
相对定位约束允许将 View_A 相对与另一个 View_B 进行定位,可以在水平和竖直两个方向上约束控件。下面是代码示例:
<Button
android:id="@+id/btn_a"
android:layout_width="100dp"
android:layout_height="45dp"
android:gravity="center"
android:text="A" />
<Button
android:id="@+id/btn_b"
android:layout_width="100dp"
android:layout_height="45dp"
android:gravity="center"
android:text="B"
app:layout_constraintStart_toEndOf="@id/btn_a"/>
app:layout_constraintStart_toEndOf="id",就代表 button b 的开始位置(start)相对 button a 的结束(end)位置。当然也可以使用 left/right 形式,一般表示的效果是一样的(使用 start/end 方式一般是为了兼容阿拉伯等地区软件时候方便适配UI,推荐按转start/end 方式写布局)。
app:layout_constraintLeft_toRightOf="@id/btn_a"
效果图:

<Button
android:id="@+id/btn_a"
android:layout_width="100dp"
android:layout_height="45dp"
android:gravity="center"
android:text="A" />
<Button
android:layout_width="100dp"
android:layout_height="45dp"
android:gravity="center"
android:text="B"
app:layout_constraintTop_toBottomOf="@id/btn_a" />
同理 app:layout_constraintTop_toBottomOf="id" 代表 button b 的顶部位置(top)相对 button a 的底部(bottom)位置。

ConstraintLayout 支持的相对定位约束属性包括:
- app:layout_constraintStart_toStartOf=""
- app:layout_constraintStart_toEndOf=""
- app:layout_constraintEnd_toEndOf=""
- app:layout_constraintEnd_toStartOf=""
- app:layout_constraintLeft_toLeftOf=""
- app:layout_constraintLeft_toRightOf=""
- app:layout_constraintRight_toRightOf=""
- app:layout_constraintRight_toLeftOf=""
- app:layout_constraintTop_toTopOf=""
- app:layout_constraintTop_toBottomOf="@id/btn_a"
- app:layout_constraintBottom_toBottomOf=""
- app:layout_constraintBottom_toTopOf=""
- app:layout_constraintBaseline_toBaselineOf=""
- app:layout_constraintBaseline_toBottomOf=""
- app:layout_constraintBaseline_toTopOf=""
2. 边距

设置 View_B 相对 View_A 有20dp的边距。
<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">
<Button
android:id="@+id/btn_a"
android:layout_width="100dp"
android:layout_height="45dp"
android:gravity="center"
android:text="A" />
<Button
android:layout_width="100dp"
android:layout_height="45dp"
android:layout_marginStart="20dp"
android:gravity="center"
android:text="B"
app:layout_constraintStart_toEndOf="@id/btn_a" />
</androidx.constraintlayout.widget.ConstraintLayout>
边距设置支持的属性有:
- android:layout_marginStart=""
- android:layout_marginEnd=""
- android:layout_marginLeft=""
- android:layout_marginRight=""
- android:layout_marginTop=""
- android:layout_marginBottom=""
ConstraintLayout 还支持隐藏控件下继续设置边距,如 View_A 隐藏后 View_B 不会变为紧贴屏幕边缘。效果图:

<Button
android:id="@+id/btn_a"
android:layout_width="100dp"
android:layout_height="45dp"
android:gravity="center"
android:text="A"
android:visibility="gone" />
<Button
android:layout_width="100dp"
android:layout_height="45dp"
android:layout_marginStart="20dp"
android:gravity="center"
android:text="B"
app:layout_constraintStart_toEndOf="@id/btn_a"
app:layout_goneMarginStart="40dp"/>
支持设置控件隐藏后的边距属性:
- app:layout_goneMarginStart=""
- app:layout_goneMarginEnd=""
- app:layout_goneMarginLeft=""
- app:layout_goneMarginRight=""
- app:layout_goneMarginTop=""
- app:layout_goneMarginBottom=""
- app:layout_goneMarginBaseline=""
3.居中和偏移
想要设置view居中可以采用下面的代码:
<Button
android:id="@+id/btn_a"
android:layout_width="100dp"
android:layout_height="45dp"
android:gravity="center"
android:text="A"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

使用 layout_constraintStart_toStartOf 和 layout_constraintEnd_toEndOf 把 View 两侧约束到根布局(parent)即可。
除了使用约束来居中,ConstraintLayout 还提供了另一种更强大的方式,不仅可以用来设置居中,还可以设置距离屏幕左侧(右侧)偏移量和权重。
<Button
android:id="@+id/btn_a"
android:layout_width="100dp"
android:layout_height="45dp"
android:gravity="center"
android:text="A"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
- layout_constraintHorizontal_bias
- layout_constraintVertical_bias
使用bias来布局,start和end(left和right)是不可以省略的,否则bias偏移不起作用。
偏移值在 0-1之间,0 靠近左侧或底部,1 靠近右侧或顶部。效果图如下:

4. 环形定位
在 ConstraintLayout 以前想要实现环形定位通常会采用自定义布局(继承 FrameLayout 或 RelativeLayout)来实现,如果需要复杂交互和动画且View数量不固定,自定义View是最佳答案。若只是静态显示且数量固定的View,复杂的自定义就不够高效和简洁了。
ConstaintLayout 提供的属性支持环形定位:
- app:layout_constraintCircle:设置引用控件的id;
- app:layout_constraintCircleAngle:控件到引用控件中心的距离;
- app:layout_constraintCircleRadius:控件相对于引用控件的角度(0-360)。
代码示例:
<ImageView
android:id="@+id/iv_sun"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/icon_sun"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_mercury"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_mercury"
app:layout_constraintCircle="@id/iv_sun"
app:layout_constraintCircleAngle="45"
app:layout_constraintCircleRadius="100dp" />

浙公网安备 33010602011771号