一、四个布局项目概览
根据Chapter02的典型结构,通常包含以下四个布局示例项目:
- LinearLayout - 线性布局
- RelativeLayout - 相对布局
- ConstraintLayout - 约束布局
- FrameLayout/TableLayout - 帧布局/表格布局
二、项目1:LinearLayout(线性布局)
项目创建与运行
xml
<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<!-- 垂直方向示例 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="线性布局示例"
android:textSize="20sp"
android:textStyle="bold"
android:gravity="center"
android:padding="10dp"
android:background="#FFE0E0E0" />
<!-- 水平线性布局示例 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="16dp">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="按钮1"
android:background="#FF4CAF50" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="按钮2"
android:background="#FF2196F3"
android:layout_marginStart="8dp" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="按钮3"
android:background="#FFFF9800"
android:layout_marginStart="8dp" />
</LinearLayout>
<!-- 权重分配示例 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="权重分配示例"
android:layout_marginTop="20dp"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="#FFFF5722" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FF9C27B0" />
</LinearLayout>
</LinearLayout>
核心特性介绍
java
// MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 线性布局特点演示
LinearLayout mainLayout = findViewById(R.id.main_layout);
// 可以动态修改方向
// mainLayout.setOrientation(LinearLayout.HORIZONTAL);
}
}
LinearLayout特点:
- 方向控制:通过
android:orientation控制垂直(vertical)或水平(horizontal) - 权重分配:使用
android:layout_weight按比例分配空间 - gravity vs layout_gravity:前者控制子控件内容对齐,后者控制子控件在父布局中的位置
三、项目2:RelativeLayout(相对布局)
布局文件
xml
<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<!-- 居中标题 -->
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="相对布局示例"
android:textSize="20sp"
android:textStyle="bold"
android:layout_centerHorizontal="true"
android:padding="10dp" />
<!-- 相对于父容器定位 -->
<Button
android:id="@+id/btnCenter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="居中按钮"
android:layout_centerInParent="true" />
<!-- 相对于其他控件定位 -->
<Button
android:id="@+id/btnAbove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="在上方"
android:layout_above="@id/btnCenter"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp" />
<Button
android:id="@+id/btnBelow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="在下方"
android:layout_below="@id/btnCenter"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp" />
<!-- 边缘对齐 -->
<Button
android:id="@+id/btnLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="左对齐"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="16dp"
android:layout_marginBottom="30dp" />
<Button
android:id="@+id/btnRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="右对齐"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="16dp"
android:layout_marginBottom="30dp" />
<!-- 相对于其他控件的边缘对齐 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="对齐标题右侧"
android:layout_toRightOf="@id/title"
android:layout_alignTop="@id/title"
android:layout_marginStart="10dp"
android:background="#FFE0E0E0"
android:padding="5dp" />
</RelativeLayout>
核心特性
java
// 动态添加相对布局关系
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
params.addRule(RelativeLayout.BELOW, R.id.title);
params.addRule(RelativeLayout.CENTER_HORIZONTAL);
RelativeLayout特点:
- 相对定位:控件可以相对于父容器或其他控件定位
- 常用规则:
layout_above,layout_below,layout_toLeftOf,layout_toRightOf - 对齐方式:
alignParentTop,alignParentBottom,centerInParent等
四、项目3:ConstraintLayout(约束布局)
布局文件
xml
<!-- activity_main.xml -->
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<!-- 标题:约束到父容器顶部 -->
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="约束布局示例"
android:textSize="20sp"
android:textStyle="bold"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- 约束链:水平链 -->
<Button
android:id="@+id/btnLeft"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="左边按钮"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/btnCenter"
app:layout_constraintHorizontal_chainStyle="spread"
android:layout_marginTop="30dp" />
<Button
android:id="@+id/btnCenter"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="中间按钮"
app:layout_constraintTop_toTopOf="@id/btnLeft"
app:layout_constraintStart_toEndOf="@id/btnLeft"
app:layout_constraintEnd_toStartOf="@id/btnRight" />
<Button
android:id="@+id/btnRight"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="右边按钮"
app:layout_constraintTop_toTopOf="@id/btnLeft"
app:layout_constraintStart_toEndOf="@id/btnCenter"
app:layout_constraintEnd_toEndOf="parent" />
<!-- 百分比定位 -->
<Button
android:id="@+id/btnPercent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="百分比定位"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_constraintHorizontal_bias="0.7" />
<!-- 圆形定位 -->
<ImageView
android:id="@+id/centerCircle"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#FF2196F3"
android:src="@drawable/ic_launcher_foreground"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="圆形定位"
app:layout_constraintCircle="@id/centerCircle"
app:layout_constraintCircleRadius="80dp"
app:layout_constraintCircleAngle="45deg" />
<!-- 屏障(Barrier)示例 -->
<TextView
android:id="@+id/label1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标签1:"
android:textSize="14sp"
app:layout_constraintTop_toBottomOf="@id/btnPercent"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/label2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标签2:"
android:textSize="14sp"
app:layout_constraintTop_toBottomOf="@id/label1"
app:layout_constraintStart_toStartOf="parent" />
<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="label1,label2" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="输入内容"
app:layout_constraintTop_toTopOf="@id/label1"
app:layout_constraintStart_toEndOf="@id/barrier"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginStart="10dp" />
<!-- 分组(Group)示例 -->
<androidx.constraintlayout.widget.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="btnPercent,centerCircle"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
需要在build.gradle中添加依赖
gradle
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}
ConstraintLayout特点:
- 扁平化布局:减少嵌套层级,提高性能
- 相对约束:类似RelativeLayout但更灵活
- 比例控制:支持百分比、偏差(bias)定位
- 高级功能:链(Chain)、屏障(Barrier)、分组(Group)、圆形定位(Circular positioning)
五、项目4:FrameLayout(帧布局)
布局文件
xml
<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="@drawable/ic_launcher_foreground"
android:foregroundGravity="bottom|end">
<!-- 底层:全屏背景 -->
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFE0E0E0" />
<!-- 中层:居中卡片 -->
<androidx.cardview.widget.CardView
android:layout_width="300dp"
android:layout_height="200dp"
android:layout_gravity="center"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="帧布局示例"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="@+id/btnOverlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="覆盖按钮"
android:layout_marginTop="16dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- 顶层:浮动按钮 -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:src="@android:drawable/ic_dialog_email"
android:layout_margin="16dp"
app:backgroundTint="#FF2196F3" />
<!-- 加载指示器 -->
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
动态管理多个层
java
public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar;
private FloatingActionButton fab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progressBar);
fab = findViewById(R.id.fab);
// 演示层的切换
fab.setOnClickListener(v -> {
progressBar.setVisibility(View.VISIBLE);
fab.setVisibility(View.GONE);
// 模拟加载
new Handler().postDelayed(() -> {
progressBar.setVisibility(View.GONE);
fab.setVisibility(View.VISIBLE);
}, 2000);
});
}
}
FrameLayout特点:
- 层叠显示:所有子控件默认堆叠在左上角
- 简单轻量:最简单的布局容器
- 常用场景:Fragment容器、加载动画叠加层、浮动按钮
- 前景属性:支持foreground和foregroundGravity
六、四种布局对比总结
| 布局类型 | 适用场景 | 优点 | 缺点 | 性能 |
|---|---|---|---|---|
| LinearLayout | 简单线性排列 | 简单直观,权重分配方便 | 复杂布局需要嵌套 | 中等 |
| RelativeLayout | 相对位置关系 | 减少嵌套层级 | 依赖关系复杂难维护 | 较好 |
| ConstraintLayout | 复杂自适应布局 | 扁平化,功能强大 | 学习曲线较陡 | 最佳 |
| FrameLayout | 单视图或叠加层 | 最轻量简单 | 多视图会重叠 | 最佳 |
七、运行这些项目
步骤:
- 在Android Studio中分别创建4个项目,命名对应布局类型
- 将对应的XML代码复制到
activity_main.xml - 确保
build.gradle包含必要的依赖(特别是ConstraintLayout需要添加) - 点击运行按钮,选择模拟器或真机运行
常见问题解决:
- Gradle同步失败:检查网络连接,使用国内镜像源
- 布局不显示:检查Activity是否正确设置setContentView
- 约束布局依赖缺失:在app/build.gradle中添加constraintlayout依赖
这四种布局各有特色,掌握它们能够应对Android开发中99%的界面布局需求。建议在实际开发中优先使用ConstraintLayout,它在性能和灵活性上都表现最佳。