
ConstraintLayout 是 Android 开发中功能强大且灵活的布局容器,自 Android Studio 2.2 起成为默认布局。它通过约束(Constraints)来定位和排列 UI 组件,能够创建复杂的、扁平化的视图层次结构,从而提升性能并简化布局设计。
本教程从基础概念到高级技巧,带你全面掌握 ConstraintLayout。
LinearLayout 或 PercentRelativeLayout。每个 View 必须至少有 水平和垂直方向各一个约束,否则在预览中会“漂浮”。
left, right, start, endtop, bottom, baseline正确:
app:layout_constraintTop_toTopOf="parent"+app:layout_constraintStart_toStartOf="parent"错误:只设置了
top没有start或end
类型 | 示例 | 说明 |
|---|---|---|
toStartOf | app:layout_constraintStart_toEndOf="@+id/button1" | 当前控件的 start 对齐到目标控件的 end |
toEndOf | app:layout_constraintEnd_toStartOf="@+id/button2" | 当前控件的 end 对齐到目标控件的 start |
toTopOf | app:layout_constraintTop_toBottomOf="@+id/text" | 当前控件的 top 对齐到目标控件的 bottom |
toBottomOf | app:layout_constraintBottom_toTopOf="@+id/image" | 当前控件的 bottom 对齐到目标控件的 top |
toBaselineOf | app:layout_constraintBaseline_toBaselineOf="@+id/text2" | 基线对齐,常用于 TextView |
<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/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello ConstraintLayout!"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>android:layout_width="0dp" <!-- match_constraint -->
android:layout_height="wrap_content"
0dp 表示“匹配约束”(Match Constraint),即根据约束自动计算大小。app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="16dp"
支持 marginStart, marginTop, marginEnd, marginBottom。⚠️ 注意:margin 必须配合约束使用,否则无效。
居中
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"偏移(Bias)
app:layout_constraintHorizontal_bias="0.3" <!-- 水平偏移 30% -->
app:layout_constraintVertical_bias="0.7" <!-- 垂直偏移 70% -->
值范围 0.0 到 1.0,默认 0.5(居中)。让 View 保持宽高比。
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />效果:图片保持 16:9 比例。
支持 H,16:9(固定高度)或 W,16:9(固定宽度)。
一组水平或垂直排列的控件,可实现类似 LinearLayout 的效果,但更灵活。
创建链 在 Android Studio 中:
选中多个控件 右键 → Chains → Create Horizontal Chain 或 Vertical Chain 链模式 通过 app:layout_constraintHorizontal_chainStyle 控制:
spread:均匀分布(默认) spread_inside:两端对齐,内部均匀 packed:紧凑排列,可配合 bias 定位
<Button
android:id="@+id/btn1"
...
app:layout_constraintHorizontal_chainStyle="packed" />
<Button
android:id="@+id/btn2"
... />
<Button
android:id="@+id/btn3"
... />不可见的辅助线,用于对齐多个控件。
<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" />
其他控件可以约束到 guideline:<TextView
app:layout_constraintStart_toStartOf="@+id/guideline" />用途:创建 30% 宽度的布局分割。
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="textView1,textView2" />右侧控件可以约束到 barrier,避免被左侧长文本覆盖。
控制一组控件的可见性。
<androidx.constraintlayout.widget.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="image1,image2,text3" />Java/Kotlin 中:
group.setVisibility(View.GONE); // 隐藏所有引用的控件占位符,可动态替换为其他控件。
<androidx.constraintlayout.widget.Placeholder
android:id="@+id/placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:content="@+id/target_view" />避免 findViewById,提升代码安全性和可读性。
避免同时设置 start 和 end 约束(除非宽度为 0dp)。
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.connect(R.id.button, ConstraintSet.TOP, R.id.parent, ConstraintSet.BOTTOM);
constraintSet.applyTo(constraintLayout);适用于动画或动态 UI 变化。
问题 | 原因 | 解决方案 |
|---|---|---|
控件“漂浮” | 缺少约束 | 为每个方向添加至少一个约束 |
宽高不生效 | 未使用 0dp | 设置 layout_width/height=“0dp” |
margin 不起作用 | 未正确约束 | 先设置约束,再加 margin |
布局错乱 | 约束冲突 | 检查 XML 或使用 Layout Inspector 调试 |
推荐:
** 避免:**