免费建站自己做个网站好还是做别人会员好
ConstraintLayout 的核心思想是通过 约束(Constraints) 来定义视图之间的关系。每个视图都需要在水平和垂直方向上至少有一个约束,否则视图会默认放置在左上角(0,0)位置。
约束的类型
相对于父布局的约束:将视图的边与父布局的边对齐。
加粗样式相对于其他视图的约束:将视图的边与其他视图的边对齐。
引导线(Guideline):一种不可见的辅助线,用于创建动态约束。
屏障(Barrier):根据一组视图的动态位置自动调整约束。
链(Chain):将多个视图在水平或垂直方向上连接起来,形成一种特殊的关系。
在 build.gradle 中添加 ConstraintLayout 的依赖:
dependencies {implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
}
下面我会通过 详细的示例 来讲解 ConstraintLayout 的使用,涵盖基本布局、引导线、链、屏障、组以及动态修改约束等内容。每个示例都会附带代码和说明。
1. 基本布局示例
目标:实现一个简单的界面,包含两个按钮和一个文本框。
按钮1位于左上角。
按钮2位于右上角。
文本框位于按钮1和按钮2的下方,水平居中。
代码:
<androidx.constraintlayout.widget.ConstraintLayoutxmlns: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"><!-- 按钮1:左上角 --><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 1"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"android:layout_marginTop="16dp"android:layout_marginStart="16dp"/><!-- 按钮2:右上角 --><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 2"app:layout_constraintTop_toTopOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="16dp"android:layout_marginEnd="16dp"/><!-- 文本框:水平居中,位于按钮1和按钮2的下方 --><TextViewandroid:id="@+id/textView"android:layout_width="0dp"android:layout_height="wrap_content"android:text="Hello, ConstraintLayout!"android:gravity="center"android:padding="16dp"app:layout_constraintTop_toBottomOf="@id/button1"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="16dp"android:layout_marginStart="16dp"android:layout_marginEnd="16dp"/></androidx.constraintlayout.widget.ConstraintLayout>
说明:
按钮1和按钮2分别通过 app:layout_constraintTop_toTopOf 和 app:layout_constraintStart_toStartOf(或 **app:layout_constraintEnd_toEndOf)**约束到父布局的顶部和左右边缘。
文本框通过 app:layout_constraintTop_toBottomOf 约束到按钮1的下方,并通过 app:layout_constraintStart_toStartOf 和 app:layout_constraintEnd_toEndOf 实现水平居中。
2. 引导线(Guideline)示例
目标:使用垂直引导线将界面分为左右两部分,左侧放置一个按钮,右侧放置一个文本框。
代码:
<androidx.constraintlayout.widget.ConstraintLayoutxmlns: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"><!-- 垂直引导线,位于父布局的50%位置 --><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.5"/><!-- 按钮:位于引导线左侧 --><Buttonandroid:id="@+id/button"android:layout_width="0dp"android:layout_height="wrap_content"android:text="Button"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toStartOf="@id/guideline"android:layout_marginTop="16dp"android:layout_marginStart="16dp"android:layout_marginEnd="16dp"/><!-- 文本框:位于引导线右侧 --><TextViewandroid:id="@+id/textView"android:layout_width="0dp"android:layout_height="wrap_content"android:text="This is the right side."android:gravity="center"android:padding="16dp"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toEndOf="@id/guideline"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="16dp"android:layout_marginStart="16dp"android:layout_marginEnd="16dp"/></androidx.constraintlayout.widget.ConstraintLayout>
说明:
引导线通过 app:layout_constraintGuide_percent=“0.5” 将界面分为左右两部分。
按钮的 app:layout_constraintEnd_toStartOf 约束到引导线,文本框的 app:layout_constraintStart_toEndOf 约束到引导线。
3. 链(Chain)示例
目标:创建水平链,包含三个按钮,均匀分布。
代码:
<androidx.constraintlayout.widget.ConstraintLayoutxmlns: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"><!-- 按钮1:链的起始 --><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 1"app:layout_constraintHorizontal_chainStyle="spread"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toStartOf="@id/button2"android:layout_marginStart="16dp"android:layout_marginEnd="8dp"/><!-- 按钮2:链的中间 --><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 2"app:layout_constraintStart_toEndOf="@id/button1"app:layout_constraintEnd_toStartOf="@id/button3"android:layout_marginStart="8dp"android:layout_marginEnd="8dp"/><!-- 按钮3:链的结束 --><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 3"app:layout_constraintStart_toEndOf="@id/button2"app:layout_constraintEnd_toEndOf="parent"android:layout_marginStart="8dp"android:layout_marginEnd="16dp"/></androidx.constraintlayout.widget.ConstraintLayout>
说明:
通过 app:layout_constraintHorizontal_chainStyle=“spread” 设置链的类型为均匀分布。
每个按钮通过 app:layout_constraintStart_toEndOf 和 app:layout_constraintEnd_toStartOf 连接到下一个按钮。
4. 屏障(Barrier)示例
目标:根据两个按钮的动态宽度,创建一个屏障,使文本框始终位于较长的按钮下方。
代码:
<androidx.constraintlayout.widget.ConstraintLayoutxmlns: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"><!-- 按钮1 --><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Short Button"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"android:layout_marginTop="16dp"android:layout_marginStart="16dp"/><!-- 按钮2 --><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Longer Button Text"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toEndOf="@id/button1"android:layout_marginTop="16dp"android:layout_marginStart="16dp"/><!-- 屏障:位于按钮1和按钮2的结束边 --><androidx.constraintlayout.widget.Barrierandroid:id="@+id/barrier"android:layout_width="wrap_content"android:layout_height="wrap_content"app:barrierDirection="end"app:constraint_referenced_ids="button1,button2"/><!-- 文本框:位于屏障下方 --><TextViewandroid:id="@+id/textView"android:layout_width="0dp"android:layout_height="wrap_content"android:text="This is below the longer button."android:gravity="center"android:padding="16dp"app:layout_constraintTop_toBottomOf="@id/barrier"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="16dp"/></androidx.constraintlayout.widget.ConstraintLayout>
说明:
屏障通过 app:barrierDirection=“end” 动态调整位置,始终位于按钮1和按钮2的结束边。
文本框通过 app:layout_constraintTop_toBottomOf 约束到屏障的下方。
5. 动态修改约束
目标:在代码中动态修改按钮的位置。
代码:
ConstraintLayout constraintLayout = findViewById(R.id.constraintLayout);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);// 将按钮1移动到父布局的右下角
constraintSet.connect(R.id.button1, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 16);
constraintSet.connect(R.id.button1, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 16);
constraintSet.applyTo(constraintLayout);
说明:
使用 ConstraintSet 动态修改按钮的约束,将其移动到右下角。
通过这些示例,你可以掌握 ConstraintLayout 的核心用法和高级功能。