Android ConstraintLayout 基础
- 屏障线 Barrier
- 设置水平和垂直方向的约束关系
- 长宽比
- 链式结构
- 组
- 站位
- 辅助线
 
- 参考地址
屏障线 Barrier
以下是使用 ConstraintLayout 在 Android 中实现简单屏障线(Barrier)使用的示例代码,主要步骤如下:
首先,在 Android 项目的布局 XML 文件中,将根布局设置为 ConstraintLayout。例如创建一个名为 activity_main.xml 的布局文件(以下代码基于 Kotlin 语言环境,Java 语言使用方式类似,只是语法上稍有不同):
<?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"tools:context=".MainActivity"><!-- 创建两个视图,这里以两个 TextView 为例 --><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 1"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 2"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/textView1" /><!-- 创建屏障 --><androidx.constraintlayout.widget.Barrierandroid:id="@+id/barrier"android:layout_width="wrap_content"android:layout_height="wrap_content"app:barrierDirection="end"app:constraint_referenced_ids="textView1,textView2" /><!-- 再创建一个视图,让它根据屏障来布局 --><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button"app:layout_constraintStart_toEndOf="@id/barrier"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget ConstraintLayout>
在上述代码中:
- 首先定义了两个 TextView(textView1和textView2),它们都是靠父布局左侧(start侧)对齐并且垂直排列。
- 接着创建了一个 Barrier(barrier),通过app:constraint_referenced_ids属性指定它关联的视图为textView1和textView2,app:barrierDirection="end"表示这个屏障的方向是在关联视图的右侧(结束侧),会根据关联视图中最右侧的边界来确定自身位置。
- 最后创建了一个 Button,它的左侧(start侧)通过app:layout_constraintStart_toEndOf="@id/barrier"约束到了这个屏障的右侧,这样按钮就会位于两个TextView的右侧,并且会随着TextView中靠右侧最远的那个视图位置变化而自适应位置。
https://www.jianshu.com/p/6ee3caaa4135
设置水平和垂直方向的约束关系
-  在XML布局文件中设置约束关系(静态方式) - 水平方向约束关系: - 左对齐(start对齐): - 假设在ConstraintLayout中有一个TextView,要使其左边缘与父布局的左边缘对齐,可以这样设置:
 <TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello"app:layout_constraintStart_toStartOf="parent"/>- 这里app:layout_constraintStart_toStartOf="parent"表示将textView的start(在从左到右的布局语言环境中相当于左侧)边缘与父布局(parent)的start边缘对齐。
 
- 假设在
- 右对齐(end对齐): - 例如,要使一个Button的右边缘与父布局的右边缘对齐:
 <Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Click Me"app:layout_constraintEnd_toEndOf="parent"/>- 其中app:layout_constraintEnd_toEndOf="parent"用于将button的end(在从左到右的布局语言环境中相当于右侧)边缘与父布局的end边缘对齐。
 
- 例如,要使一个
- 水平居中对齐: - 对于一个ImageView,要使其在父布局中水平居中,可以使用以下约束:
 <ImageViewandroid:id="@+id/imageView"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"/>- 通过将imageView的start边缘与父布局的start边缘对齐,并且end边缘与父布局的end边缘对齐,就可以实现水平居中。
 
- 对于一个
 
- 左对齐(start对齐): 
- 垂直方向约束关系: - 顶部对齐(top对齐): - 假设有一个EditText,要使其顶部边缘与父布局的顶部边缘对齐:
 <EditTextandroid:id="@+id/editText"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintTop_toTopOf="parent"/>- 这里app:layout_constraintTop_toTopOf="parent"确保了editText的top边缘与父布局的top边缘对齐。
 
- 假设有一个
- 底部对齐(bottom对齐): - 例如,使一个LinearLayout的底部边缘与父布局的底部边缘对齐:
 <LinearLayoutandroid:id="@+id/linearLayout"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintBottom_toBottomOf="parent"/>- 其中app:layout_constraintBottom_toBottomOf="parent"实现了linearLayout的bottom边缘与父布局的bottom边缘对齐。
 
- 例如,使一个
- 垂直居中对齐: - 对于一个View,要使其在父布局中垂直居中,可以这样设置:
 <Viewandroid:id="@+id/view"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintTop_toTopOf="parent"app:licensePlateConstraintBottom_toBottomOf="parent"/>- 通过同时将view的top边缘与父布局的top边缘对齐,以及bottom边缘与父布局的bottom边缘对齐,实现垂直居中。
 
- 对于一个
 
- 顶部对齐(top对齐): 
 
- 水平方向约束关系: 
-  在Java代码中设置约束关系(动态方式) - 使用ConstraintSet设置水平方向约束关系:- 首先,在Activity的onCreate方法或者其他合适的方法中,获取ConstraintLayout和要设置约束的视图,以及创建ConstraintSet对象:
 import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import android.os.Bundle; import android.view.View; import android.widget.Button;public class MainActivity extends AppCompatActivity {private ConstraintLayout constraintLayout;private Button button;private ConstraintSet constraintSet;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);constraintLayout = findViewById(R.id.constraint_layout);button = findViewById(R.id.button);constraintSet = new ConstraintSet();} }- 左对齐(start对齐): - 假设要将button的start边缘与父布局的start边缘对齐,可以这样设置:
 constraintSet.clone(constraintLayout); constraintSet.connect(button.getId(), ConstraintSet.START, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintSet.START); constraintSet.applyTo(constraintLayout);- 首先通过constraintSet.clone(constraintLayout)克隆当前布局的约束集。然后使用constraintSet.connect方法,将button的START(左侧)约束连接到父布局(ConstraintLayout.LayoutParams.PARENT_ID)的START边缘。最后通过constraintSet.applyTo(constraintLayout)将修改后的约束应用到布局中。
 
- 假设要将
- 右对齐(end对齐): - 要将button的end边缘与父布局的end边缘对齐,可以使用以下代码:
 constraintSet.clone(constraintLayout); constraintSet.connect(button.getId(), ConstraintSet.END, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintSet.END); constraintSet.applyTo(constraintLayout);- 这里的逻辑与左对齐类似,只是将连接的方向改为END(右侧)。
 
- 要将
- 水平居中对齐: - 若要使button在父布局中水平居中,可以这样设置:
 constraintSet.clone(constraintLayout); constraintSet.connect(button.getId(), ConstraintSet.START, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintSet.START); constraintSet.connect(button.getId(), ConstraintSet.END, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintSet.END); constraintSet.applyTo(constraintLayout);- 通过同时将button的START和END边缘分别与父布局的START和END边缘连接,实现水平居中。
 
- 若要使
 
- 首先,在
- 使用ConstraintSet设置垂直方向约束关系:- 顶部对齐(top对齐): - 假设要将button的top边缘与父布局的top边缘对齐,可以这样设置:
 constraintSet.clone(constraintLayout); constraintSet.connect(button.getId(), ConstraintSet.TOP, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintSet.TOP); constraintSet.applyTo(constraintLayout);- 首先克隆约束集,然后使用connect方法将button的TOP(顶部)约束连接到父布局的TOP边缘,最后应用修改后的约束。
 
- 假设要将
- 底部对齐(bottom对齐): - 要将button的bottom边缘与父布局的bottom边缘对齐,可以使用以下代码:
 constraintSet.clone(constraintLayout); constraintSet.connect(button.getId(), ConstraintSet.BOTTOM, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintSet.BOTTOM); constraintSet.applyTo(constraintLayout);- 这里的逻辑与顶部对齐类似,只是将连接的方向改为BOTTOM(底部)。
 
- 要将
- 垂直居中对齐: - 若要使button在父布局中垂直居中,可以这样设置:
 constraintSet.clone(constraintLayout); constraintSet.connect(button.getId(), ConstraintSet.TOP, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintSet.TOP); constraintSet.connect(button.getId(), ConstraintSet.BOTTOM, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintSet.BOTTOM); constraintSet.applyTo(constraintLayout);- 通过同时将button的TOP和BOTTOM边缘分别与父布局的TOP和BOTTOM边缘连接,实现垂直居中。
 
- 若要使
 
- 顶部对齐(top对齐): 
 
- 使用
长宽比
-  在XML布局文件中设置长宽比约束(静态方式) - 使用app:layout_constraintDimensionRatio属性:- 例如,对于一个ImageView,想要保持其宽度和高度的特定比例(假设为16:9),可以这样设置:
 <ImageViewandroid:id="@+id/imageView"android:layout_width="0dp"android:layout_height="0dp"app:layout_constraintDimensionRatio="16:9"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"/>- 这里将layout_width和layout_height都设置为0dp,这是因为在使用长宽比约束时,需要通过其他约束(如这里的start、end、top、bottom与父布局的对齐约束)来确定视图的整体尺寸范围,然后按照指定的长宽比来分配宽度和高度。app:layout_constraintDimensionRatio="16:9"指定了宽度和高度的比例关系。
 
- 例如,对于一个
 
- 使用
-  在Java代码中设置长宽比约束(动态方式) - 使用ConstraintSet设置长宽比约束:- 首先,在Activity的onCreate方法或者其他合适的方法中获取ConstraintLayout和视图,以及创建ConstraintSet对象。以下以一个Button为例:
 import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import android.os.Bundle; import android.view.View; import android.widget.Button;public class MainActivity extends AppCompatActivity {private ConstraintLayout constraintLayout;private Button button;private ConstraintSet constraintSet;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);constraintLayout = findViewById(R.id.constraint_layout);button = findViewById(R.id.button);constraintSet = new ConstraintSet();} }- 假设要为button设置长宽比为4:3,可以这样做:
 constraintSet.clone(constraintLayout); // 设置长宽比为4:3 constraintSet.setDimensionRatio(button.getId(), "4:3"); // 需要同时设置宽度和高度的约束方式,例如都设置为WRAP_CONTENT constraintSet.constrainWidth(button.getId(), ConstraintSet.WRAP_CONTENT); constraintSet.constrainHeight(button.getId(), ConstraintSet.WRAP_CONTENT); constraintSet.applyTo(constraintLayout);- 首先通过constraintSet.clone(constraintLayout)克隆当前布局的约束集。然后使用constraintSet.setDimensionRatio(button.getId(), "4:3")设置button的长宽比为4:3。需要注意的是,同时还要通过constraintSet.constrainWidth和constraintSet.constrainHeight设置宽度和高度的约束方式(这里都设置为WRAP_CONTENT,也可以根据实际情况设置为MATCH_PARENT或固定尺寸等),最后通过constraintSet.applyTo(constraintLayout)将修改后的约束应用到布局中。
 
- 首先,在
 
- 使用
链式结构
-  链式结构在 ConstraintLayout中的概念- 在ConstraintLayout中,链式结构是一种用于管理多个视图之间布局关系的方式。它允许将一组视图按照线性方式(水平或垂直)排列,并定义它们之间的间距和对齐方式等约束。可以把它想象成一条链,链上的每个环节(视图)都与相邻的环节相互关联,并且整体链的布局受到特定规则的约束。
 
- 在
-  水平链式结构(Horizontal Chains) - 创建水平链式结构(XML方式): - 假设要创建一个水平链式结构,包含三个TextView。首先,在ConstraintLayout布局文件中进行如下设置:
 <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"><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 1"app:layout_constraintHorizontal_chainStyle="spread"app:layout_constraintStart_toStartOf="parent"/><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 2"app:layout_constraintStart_toEndOf="@id/textView1"/><TextViewandroid:id="@+id/textView3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 3"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toEndOf="@id/textView2"/> </androidx.constraintlayout.widget.ConstraintLayout>- 在这个例子中: - app:layout_constraintHorizontal_chainStyle="spread"应用在- textView1上,这定义了水平链的样式为- spread(伸展)。这种样式下,链中的视图会在水平方向上均匀分布,两端的视图分别与父布局的左右边缘对齐。
- textView1通过- app:layout_constraintStart_toStartOf="parent"与父布局的左侧对齐。- textView2通过- app:layout_constraintStart_toEndOf="@id/textView1"与- textView1的右侧连接。- textView3通过- app:layout_constraintEnd_toEndOf="parent"与父布局的右侧对齐,并且通过- app:layout_constraintStart_toEndOf="@id/textView2"与- textView2的右侧连接,这样就形成了一个水平链式结构。
 
 
- 假设要创建一个水平链式结构,包含三个
- 水平链式结构的样式(chainStyle):- spread(伸展)样式:- 如上述示例,视图会均匀分布在水平方向上,并且两端的视图会分别与父布局的左右边缘对齐。如果有剩余空间,会平均分配到每个视图之间的间距中。
 
- spread_inside(内部伸展)样式:- 与spread类似,但两端的视图不会与父布局的边缘对齐,而是链中的视图在除去两端视图与父布局边缘的间距后,在内部均匀分布。例如:
 - <TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 1"app:layout_constraintHorizontal_chainStyle="spread_inside"app:layout_constraintStart_toStartOf="parent"/>- 这样设置后,textView1和其他在链中的视图会在父布局内部更均匀地分布,两端会留出一定的间距。
 
- 与
- packed(紧凑)样式:- 链中的视图会紧密排列在一起,并且可以通过app:layout_constraintHorizontal_bias属性来控制它们在水平方向上相对于链的起始位置的偏移量。例如:
 - <TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 1"app:layout_constraintHorizontal_chainStyle="packed"app:layout_constraintStart_toStartOf="parent"/>- 视图会紧凑地排列,并且可以根据需要调整bias属性来改变它们在水平方向上的位置。
 
- 链中的视图会紧密排列在一起,并且可以通过
 
- 在Java代码中设置水平链式结构: - 首先,在Activity的onCreate方法中获取ConstraintLayout和相关视图,并创建ConstraintSet对象:
 import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import android.os.Bundle; import android.view.View; import android.widget.TextView;public class MainActivity extends AppCompatActivity {private ConstraintLayout constraintLayout;private TextView textView1;private TextView textView2;private TextView textView3;private ConstraintSet constraintSet;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);constraintLayout = findViewById(R.id.constraint_layout);textView1 = findViewById(R.id.textView1);textView2 = findViewById(R.id.textView2);textView3 = findViewById(R.id.textView3);constraintSet = new ConstraintSet();} }- 假设要将水平链式结构的样式从spread改为packed,可以这样做:
 constraintSet.clone(constraintLayout); constraintSet.setHorizontalChainStyle(textView1.getId(), ConstraintSet.CHAIN_PACKED); // 应用修改后的约束 constraintSet.applyTo(constraintLayout);- 这里通过constraintSet.setHorizontalChainStyle方法,将以textView1为头部的水平链式结构的样式修改为packed,然后应用到布局中。
 
- 首先,在
 
- 创建水平链式结构(XML方式): 
-  垂直链式结构(Vertical Chains) - 创建垂直链式结构(XML方式): - 例如,要创建一个垂直链式结构,包含三个Button,在ConstraintLayout布局文件中设置如下:
 <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"><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 1"app:layout_constraintVertical_chainStyle="spread"app:layout_constraintTop_toTopOf="parent"/><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 2"app:layout_constraintTop_toBottomOf="@id/button1"/><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 3"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintTop_toBottomOf="@id/button2"/> </androidx.constraintlayout.widget.ConstraintLayout>- 在这个例子中: - app:layout_constraintVertical_chainStyle="spread"应用在- button1上,定义了垂直链的样式为- spread(伸展)。在这种样式下,链中的视图会在垂直方向上均匀分布,两端的视图分别与父布局的上下边缘对齐。
- button1通过- app:layout_constraintTop_toTopOf="parent"与父布局的顶部对齐。- button2通过- app:layout_constraintTop_toBottomOf="@id/button1"与- button1的底部连接。- button3通过- app:layout_constraintBottom_toBottomOf="parent"与父布局的底部对齐,并且通过- app:layout_constraintTop_toBottomOf="@id/button2"与- button2的底部连接,从而形成一个垂直链式结构。
 
 
- 例如,要创建一个垂直链式结构,包含三个
- 垂直链式结构的样式(chainStyle):- 垂直链式结构的样式(spread、spread_inside、packed)与水平链式结构类似,只是方向是垂直的。它们在垂直方向上控制视图的分布和对齐方式。
 
- 垂直链式结构的样式(
- 在Java代码中设置垂直链式结构: - 首先,在Activity的onCreate方法中获取ConstraintLayout和相关视图,并创建ConstraintSet对象:
 import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import android.os.Bundle; import android.view.View; import android.widget.Button;public class MainActivity extends AppCompatActivity {private ConstraintLayout constraintLayout;private Button button1;private Button button2;private Button button3;private ConstraintSet constraintSet;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);constraintLayout = findViewById(R.id.constraint_layout);button1 = findViewById(R.id.button1);button2 = findViewById(R.id.button2);button3 = findViewById(R.id.button3);constraintSet = new ConstraintSet();} }- 假设要将垂直链式结构的样式从spread改为packed,可以这样做:
 constraintSet.clone(constraintLayout); constraintSet.setVerticalChainStyle(button1.getId(), ConstraintSet.CHAIN_PACKED); // 应用修改后的约束 constraintSet.applyTo(constraintLayout);- 这里通过constraintSet.setVerticalChainStyle方法,将以button1为头部的垂直链式结构的样式修改为packed,然后应用到布局中。
 
- 首先,在
 
- 创建垂直链式结构(XML方式): 
组
-  在XML布局文件中使用组(Groups) - 创建组的基本语法: - 在ConstraintLayout中,可以使用<androidx.constraintlayout.widget.Group>标签来创建一个组。例如,要将两个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"><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 1"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView 2"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/textView1"/><androidx.constraintlayout.widget.Groupandroid:id="@+id/group"android:layout_width="wrap_content"android:layout_height="wrap_content"app:constraint_referenced_ids="textView1,textView2"/> </androidx.constraintlayout.widget.ConstraintLayout>- 在这个例子中,<androidx.constraintlayout.widget.Group>标签有一个app:constraint_referenced_ids属性,用于指定组内包含的视图的id。这里将textView1和textView2归为一组,组的id为group。
 
- 在
- 控制组的可见性来管理视图可见性: - 可以通过在Java代码中控制组的可见性,从而同时控制组内所有视图的可见性。例如,在Activity的onCreate方法中:
 import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Group; import android.os.Bundle; import android.view.View; import android.widget.TextView;public class MainActivity extends AppCompatActivity {private ConstraintLayout constraintLayout;private TextView textView1;private TextView textView2;private Group group;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);constraintLayout = findViewById(R.id.constraint_layout);textView1 = findViewById(R.id.textView1);textView2 = findViewById(R.id.textView2);group = findViewById(R.id.group);// 隐藏组内的所有视图group.setVisibility(View.GONE);} }- 当执行group.setVisibility(View.GONE);时,组内的textView1和textView2都会被隐藏。同样,如果设置为View.VISIBLE,组内的视图都会显示。
 
- 可以通过在Java代码中控制组的可见性,从而同时控制组内所有视图的可见性。例如,在
 
- 创建组的基本语法: 
-  在Java代码中创建和管理组(动态方式) - 创建组并添加视图到组中: - 首先,在Activity的onCreate方法中获取ConstraintLayout对象,然后创建一个Group对象并添加视图到组中。以下是一个示例:
 import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Group; import android.os.Bundle; import android.view.View; import android.widget.TextView;public class MainActivity extends AppCompatActivity {private ConstraintLayout constraintLayout;private TextView textView1;private TextView textView2;private Group group;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);constraintLayout = findViewById(R.id.constraint_layout);textView1 = findViewById(R.id.textView1);textView2 = findViewById(R.id.textView2);group = new Group(constraintLayout.getContext());group.setId(View.generateViewId());group.addView(textView1);group.addView(textView2);constraintLayout.addView(group);} }- 这里首先创建了一个Group对象,然后通过setId方法为组设置一个唯一的id。接着使用addView方法将textView1和textView2添加到组中,最后将组添加到ConstraintLayout中。
 
- 首先,在
- 控制组的可见性动态管理视图可见性: - 可以在任何事件处理方法或者需要的地方控制组的可见性。例如,在一个按钮点击事件处理方法中:
 public void onButtonClick(View view) {if (group.getVisibility() == View.VISIBLE) {group.setVisibility(View.GONE);} else {group.setVisibility(View.VISIBLE);} }- 这段代码通过检查组的当前可见性状态,如果是可见的,则将组(以及组内的所有视图)隐藏;如果是隐藏的,则将组(以及组内的所有视图)显示。这样就可以通过组来方便地管理多个视图的可见性。
 
 
- 创建组并添加视图到组中: 
站位
-  Placeholder在 ConstraintLayout中的概念- Placeholder是- ConstraintLayout中的一个特殊组件,它主要用于在布局中预留一个位置,这个位置可以在运行时被其他视图替换。就像是在舞台上为某个演员(视图)预留了一个特定的站位,当需要的时候,真正的演员(视图)就可以站到这个位置上。
 
-  在XML布局文件中使用Placeholder(静态方式) - 基本使用示例: - 假设在一个ConstraintLayout布局中有一个Placeholder,并且在合适的时候要用一个TextView来替换它。首先,在布局文件中定义Placeholder和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"><androidx.constraintlayout.widget.Placeholderandroid:id="@+id/placeholder"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Replaced Text"android:visibility="gone"/> </androidx.constraintlayout.widget.ConstraintLayout>- 在这个例子中,Placeholder通过app:layout_constraintStart_toStartOf="parent"和app:layout_constraintTop_toTopOf="parent"约束在父布局的左上角。TextView的初始可见性设置为gone,因为它一开始不需要显示,等待替换Placeholder的时候再显示。
 
- 假设在一个
- 替换Placeholder的操作(在Java代码中实现):- 在Activity的onCreate方法或者其他合适的方法中,进行如下操作来替换Placeholder:
 import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Placeholder; import android.os.Bundle; import android.view.View; import android.widget.TextView;public class MainActivity extends AppCompatActivity {private ConstraintLayout constraintLayout;private Placeholder placeholder;private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);constraintLayout = findViewById(R.id.constraint_layout);placeholder = findViewById(R.id.placeholder);textView = findViewById(R.id.textView);placeholder.setContentId(textView.getId());textView.setVisibility(View.VISIBLE);} }- 首先通过placeholder.setContentId(textView.getId());语句将textView的id设置给Placeholder,这就告诉Placeholder要被textView替换。然后将textView的可见性设置为View.VISIBLE,这样textView就会显示在原来Placeholder所在的位置,完成替换操作。
 
- 在
 
- 基本使用示例: 
-  Placeholder的优势和应用场景 - 优势: - 布局灵活性:可以在布局设计阶段预先为不同类型的视图预留位置,根据运行时的条件(如用户权限、数据加载情况等)动态地填充合适的视图,而不需要频繁地修改布局结构。
- 代码可读性和可维护性:使得布局和视图替换的逻辑更加清晰。通过Placeholder的机制,开发人员可以很容易地理解某个位置上的视图是可以被替换的,并且替换的操作集中在代码中的特定部分,便于维护。
 
- 应用场景: - 动态内容展示:例如在一个新闻应用中,根据新闻类型(文字新闻、图片新闻、视频新闻等),可以在一个预留的Placeholder位置展示不同的视图来呈现新闻内容。
- 权限相关布局变化:如果一个应用中有部分功能需要特定权限才能使用,当用户权限状态改变时,可以使用Placeholder在相同位置替换不同的视图,来显示权限允许或禁止时的不同界面内容。
 
- 动态内容展示:例如在一个新闻应用中,根据新闻类型(文字新闻、图片新闻、视频新闻等),可以在一个预留的
 
- 优势: 
辅助线
-  Guideline在 ConstraintLayout中的概念- Guideline是- ConstraintLayout中的一种辅助布局工具,它本质上是一条虚拟的线,用于帮助开发者更精准地定位和约束视图。这条线可以是水平方向的,也可以是垂直方向的,并且可以设置其位置相对于布局的边界(如- parent的边缘)或者相对于布局的百分比位置,为视图的布局提供参考依据。
 
-  在XML布局文件中使用Guideline(静态方式) - 创建水平Guideline: - 例如,要创建一条水平方向的Guideline,将其位置设置为距离布局顶部30%的位置,可以这样写:
 <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"><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/horizontalGuideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"app:layout_constraintGuide_percent="0.3"/><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello"app:layout_constraintTop_toTopOf="@id/horizontalGuideline"/> </androidx.constraintlayout.widget.ConstraintLayout>- 在这个例子中,<androidx.constraintlayout.widget.Guideline>标签用于创建Guideline。android:orientation="horizontal"表示这是一条水平方向的线。app:layout_constraintGuide_percent="0.3"将Guideline的位置设置为距离布局顶部30%的高度处。然后TextView通过app:layout_constraintTop_toTopOf="@id/horizontalGuideline"将其顶部约束到这条Guideline的顶部,从而使TextView的位置与Guideline相关联。
 
- 例如,要创建一条水平方向的
- 创建垂直Guideline: - 假设要创建一条垂直方向的Guideline,位于距离布局左侧20%的位置,代码如下:
 <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"><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/verticalGuideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_begin="20%p"/><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Click Me"app:layout_constraintStart_toStartOf="@id/verticalGuideline"/> </androidx.constraintlayout.widget.ConstraintLayout>- 这里android:orientation="vertical"表示是垂直方向的Guideline。app:layout_constraintGuide_begin="20%p"将Guideline的位置设置为距离布局左侧20%(%p表示相对于父布局的百分比)。Button通过app:layout_constraintStart_toStartOf="@id/verticalGuideline"将其左侧约束到这条Guideline的左侧,确定了Button的水平位置。
 
- 假设要创建一条垂直方向的
- Guideline位置的其他设置方式: - 除了使用百分比(app:layout_constraintGuide_percent和app:layout_constraintGuide_begin)来设置位置外,还可以将Guideline直接与布局的边缘对齐。例如,将水平Guideline与布局底部对齐:
 <androidx.constraintlayout.widget.Guidelineandroid:id="@+id/bottomGuideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"app:layout_constraintGuide_end="parentBottom"/>- 这里app:layout_constraintGuide_end="parentBottom"表示将Guideline的底部与父布局的底部对齐。
 
- 除了使用百分比(
 
- 创建水平Guideline: 
-  在Java代码中使用Guideline(动态方式) - 获取和修改Guideline的位置(以垂直Guideline为例): - 首先,在Activity的onCreate方法中获取ConstraintLayout和Guideline对象:
 import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Guideline; import android.os.Bundle; import android.view.View;public class MainActivity extends AppCompatActivity {private ConstraintLayout constraintLayout;private Guideline verticalGuideline;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);constraintLayout = findViewById(R.id.constraint_layout);verticalGuideline = findViewById(R.id.verticalGuideline);} }- 假设要将垂直Guideline的位置从距离左侧20%修改为30%,可以这样做:
 import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Guideline; import android.os.Bundle; import android.view.View;public class MainActivity extends AppCompatActivity {// 前面代码省略...@Overrideprotected void onCreate(Bundle savedInstanceState) {// 前面代码省略...ConstraintLayout.LayoutParams guidelineParams = (ConstraintLayout.LayoutParams) verticalGuideline.getLayoutParams();guidelineParams.guidePercent = 0.3f;verticalGuideline.setLayoutParams(guidelineParams);} }- 首先通过verticalGuideline.getLayoutParams()获取Guideline的布局参数,然后将guidePercent属性修改为0.3f(表示30%),最后通过verticalGuideline.setLayoutParams(guidelineParams)应用修改后的布局参数,从而改变Guideline的位置。
 
- 首先,在
 
- 获取和修改Guideline的位置(以垂直Guideline为例): 
通过使用Guideline,可以更灵活地控制视图的布局,特别是在需要按照一定比例或者相对于布局边界进行精确布局的情况下,能够大大提高布局的准确性和可维护性。
参考地址
豆包AI