Android Studio布局资源的四种常用类型及运行过程

5 阅读7分钟

一、四个布局项目概览

根据Chapter02的典型结构,通常包含以下四个布局示例项目:

  1. LinearLayout - 线性布局
  2. RelativeLayout - 相对布局
  3. ConstraintLayout - 约束布局
  4. 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_abovelayout_belowlayout_toLeftOflayout_toRightOf
  • 对齐方式alignParentTopalignParentBottomcenterInParent

四、项目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单视图或叠加层最轻量简单多视图会重叠最佳

七、运行这些项目

步骤:

  1. 在Android Studio中分别创建4个项目,命名对应布局类型
  2. 将对应的XML代码复制到activity_main.xml
  3. 确保build.gradle包含必要的依赖(特别是ConstraintLayout需要添加)
  4. 点击运行按钮,选择模拟器或真机运行

常见问题解决:

  • Gradle同步失败:检查网络连接,使用国内镜像源
  • 布局不显示:检查Activity是否正确设置setContentView
  • 约束布局依赖缺失:在app/build.gradle中添加constraintlayout依赖

这四种布局各有特色,掌握它们能够应对Android开发中99%的界面布局需求。建议在实际开发中优先使用ConstraintLayout,它在性能和灵活性上都表现最佳。