ConstraintLayout 核心用法详解(一):相对定位、边距、偏移与环形定位

ConstraintLayout布局学习1

2016年Google推出了 ConstraintLayout 布局,可以译为“约束布局”,并在 Android Studio 2.3 创建的默认布局中都采用ConstraintLayout 作为最外层布局。

ConstraintLayout 很好的解决了旧布局方式的弊端(LinearLayoutRelativeLayout 等):布局层级多导致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" />

环形图定位

5. 参考资料

posted @ 2026-09-03 23:47  换元不配限  阅读(2)  评论(0)    收藏  举报