Android 控件与布局全面解析

文章目录

    • 一、引言
    • [二、Android 布局(Layout)](#二、Android 布局(Layout))
      • [2.1 LinearLayout(线性布局)](#2.1 LinearLayout(线性布局))
      • [2.2 RelativeLayout(相对布局)](#2.2 RelativeLayout(相对布局))
      • [2.3 ConstraintLayout(约束布局)](#2.3 ConstraintLayout(约束布局))
      • [2.4 FrameLayout(帧布局)](#2.4 FrameLayout(帧布局))
      • [2.5 布局核心属性必知必会](#2.5 布局核心属性必知必会)
        • [`layout_width` 与 `layout_height`](#layout_widthlayout_height)
        • [dp vs px vs sp](#dp vs px vs sp)
        • [margin vs padding](#margin vs padding)
        • [gravity vs layout_gravity](#gravity vs layout_gravity)
    • [三、Android 常用控件(Widget)](#三、Android 常用控件(Widget))
      • [3.1 TextView ------ 文本显示](#3.1 TextView —— 文本显示)
      • [3.2 EditText ------ 文本输入](#3.2 EditText —— 文本输入)
      • [3.3 Button ------ 按钮](#3.3 Button —— 按钮)
      • [3.4 ImageView ------ 图片展示](#3.4 ImageView —— 图片展示)
      • [3.5 ListView ------ 列表展示](#3.5 ListView —— 列表展示)
      • [3.6 RecyclerView ------ 更强大的列表](#3.6 RecyclerView —— 更强大的列表)
      • [3.7 Toast ------ 轻量提示](#3.7 Toast —— 轻量提示)
      • [3.8 CheckBox 与 RadioButton](#3.8 CheckBox 与 RadioButton)
      • [3.9 Switch(开关)](#3.9 Switch(开关))
      • [3.10 SeekBar(滑动条)](#3.10 SeekBar(滑动条))
    • [四、ViewHolder 性能优化详解](#四、ViewHolder 性能优化详解)
    • 五、常见事件监听总结
    • 六、总结

一、引言

对于刚接触 Android 开发的新手来说,控件(Widget)布局(Layout) 是绕不开的两座大山。它们共同构成了 App 的"脸面"------用户看到的一切界面,都是由布局搭建框架、再由控件填充内容而成的。

本文将从零开始,系统地介绍 Android 中常用的布局和控件,配合实际代码示例,帮助你快速上手 Android UI 开发。


二、Android 布局(Layout)

布局的作用是管理子控件之间的位置关系,相当于一个"容器"。Android 提供了多种布局,各有适用场景。

2.1 LinearLayout(线性布局)

LinearLayout 是最基础、最常用的布局。它会将子控件按照**水平(horizontal)垂直(vertical)**方向依次排列。

xml 复制代码
<!-- 垂直排列 -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button android:text="按钮1" ... />
    <Button android:text="按钮2" ... />
    <Button android:text="按钮3" ... />

</LinearLayout>

如果把 orientation 改成 horizontal,三个按钮就会水平排成一行。

适用场景: 简单的列表、表单、工具栏等线性排列的界面。


2.2 RelativeLayout(相对布局)

RelativeLayout 允许子控件通过相对位置来定位,比如"在 A 的右边"、"与 B 底部对齐"等。

xml 复制代码
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/label"
        android:text="用户名:"
        android:layout_alignParentLeft="true" />

    <EditText
        android:id="@+id/input"
        android:layout_toRightOf="@id/label"
        android:layout_alignBaseline="@id/label" />

    <Button
        android:text="提交"
        android:layout_below="@id/input"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

常用相对定位属性:

属性 含义
layout_below 在指定控件的下方
layout_above 在指定控件的上方
layout_toRightOf 在指定控件的右侧
layout_toLeftOf 在指定控件的左侧
layout_alignParentBottom 与父容器底部对齐
layout_centerHorizontal 在父容器中水平居中

适用场景: 需要控件之间有位置依赖关系的复杂界面。


2.3 ConstraintLayout(约束布局)

ConstraintLayout 是 Google 官方推荐的布局,功能最强大。它通过**约束(Constraint)**来描述控件之间的关系,既能实现扁平化布局(避免多层嵌套),又能灵活适配各种屏幕。

xml 复制代码
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/avatar"
        android:layout_width="80dp"
        android:layout_height="80dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginStart="16dp" />

    <TextView
        android:id="@+id/name"
        android:text="张三"
        app:layout_constraintStart_toEndOf="@id/avatar"
        app:layout_constraintTop_toTopOf="@id/avatar"
        android:layout_marginStart="12dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

适用场景: 几乎适用所有场景,尤其是复杂界面、需要适配多屏幕的情况。


2.4 FrameLayout(帧布局)

FrameLayout 是最简单的布局,所有子控件默认层叠在左上角,后添加的会覆盖先添加的。

xml 复制代码
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:src="@drawable/background"
        android:scaleType="centerCrop"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:text="层叠在上方的文字"
        android:layout_gravity="center"
        android:textColor="#FFFFFF" />

</FrameLayout>

适用场景: 单一子控件的占位、悬浮遮罩层、Fragment 容器。


2.5 布局核心属性必知必会

无论用哪种布局,以下属性是每个开发者都必须掌握的:

layout_widthlayout_height
含义
match_parent 尺寸与父容器一致
wrap_content 根据内容自动调整大小
具体数值(如 100dp 固定尺寸
dp vs px vs sp
单位 含义 使用场景
px 屏幕物理像素 不推荐直接使用
dp 密度无关像素,在不同密度屏幕上物理大小一致 控件宽高、间距
sp 可伸缩像素,受系统字体大小设置影响 文字大小
xml 复制代码
android:layout_width="100dp"
android:textSize="16sp"
android:layout_margin="8dp"
margin vs padding
  • margin (外边距):控件与其他控件之间的距离

  • padding (内边距):控件内容与自身边界之间的距离

    ┌─────────── margin ───────────┐
    │ ┌────── padding ──────┐ │
    │ │ │ │
    │ │ 内容区域 │ │
    │ │ │ │
    │ └─────────────────────┘ │
    └──────────────────────────────┘

xml 复制代码
android:layout_margin="16dp"   <!-- 与其他控件的间距 -->
android:padding="12dp"         <!-- 内容与边框的间距 -->
gravity vs layout_gravity
属性 作用对象 含义
android:gravity 控件自身内容 内容在控件内部的摆放位置
android:layout_gravity 控件在父容器中 控件在父容器中的摆放位置
xml 复制代码
<!-- 文字在 TextView 内部居中 -->
<TextView android:gravity="center" ... />

<!-- TextView 本身在父容器中居中 -->
<TextView android:layout_gravity="center" ... />

三、Android 常用控件(Widget)

3.1 TextView ------ 文本显示

TextView 是最基本的控件,用于在屏幕上展示文字。

xml 复制代码
<TextView
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello Android"
    android:textSize="18sp"
    android:textColor="#333333"
    android:textStyle="bold"
    android:maxLines="2"
    android:ellipsize="end" />

常用属性速查:

属性 说明
android:text 显示的文本内容
android:textSize 文字大小(单位 sp)
android:textColor 文字颜色
android:textStyle 样式:normal/bold/italic
android:maxLines 最大行数,超出后省略
android:ellipsize 省略位置:end/middle/start
android:gravity 文字对齐方式

Java 代码动态设置:

java 复制代码
TextView tv = findViewById(R.id.title);
tv.setText("新的文字");
tv.setTextColor(Color.RED);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);

3.2 EditText ------ 文本输入

EditText 继承自 TextView,允许用户输入和编辑文字。

xml 复制代码
<EditText
    android:id="@+id/input"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="请输入用户名"
    android:inputType="text"
    android:maxLength="20" />

inputType 常用值:

说明
text 普通文本
textPassword 密码(显示为圆点)
number 纯数字
phone 电话号码
textEmailAddress 邮箱地址
textMultiLine 多行文本

3.3 Button ------ 按钮

Button 是触发操作的核心控件,用户点击后执行相应逻辑。

xml 复制代码
<Button
    android:id="@+id/btn_submit"
    android:text="提交"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="onSubmitClick" />

Java 中设置点击事件(两种方式):

java 复制代码
// 方式一:匿名内部类
Button btn = findViewById(R.id.btn_submit);
btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(MainActivity.this, "按钮被点击了", Toast.LENGTH_SHORT).show();
    }
});

// 方式二:Lambda 表达式(推荐)
btn.setOnClickListener(v -> {
    Toast.makeText(MainActivity.this, "按钮被点击了", Toast.LENGTH_SHORT).show();
});

3.4 ImageView ------ 图片展示

ImageView 用于在界面上展示图片资源。

xml 复制代码
<ImageView
    android:id="@+id/image"
    android:layout_width="120dp"
    android:layout_height="120dp"
    android:src="@drawable/sample_image"
    android:scaleType="centerCrop"
    android:contentDescription="示例图片" />

scaleType 详解:

效果
centerCrop 等比缩放填满控件,超出部分裁剪 ★推荐
fitCenter 等比缩放,居中显示,不裁剪
fitXY 拉伸填满,可能导致变形
center 不缩放,居中显示原图
centerInside 等比缩放至完全显示在控件内

Java 代码动态设置:

java 复制代码
ImageView imageView = findViewById(R.id.image);
imageView.setImageResource(R.drawable.new_image);

// 使用第三方库加载网络图片(如 Glide)
// Glide.with(this).load("https://example.com/image.jpg").into(imageView);

3.5 ListView ------ 列表展示

ListView 是展示大量同类型数据的最经典控件,采用 MVC 架构

复制代码
Model(数据)  →  Adapter(适配器/桥梁)  →  View(列表控件)

使用 ListView 的四大步骤:

第一步:创建数据模型

java 复制代码
public class Fruit {
    private String name;
    private int imageId;

    public Fruit(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }

    public String getName() { return name; }
    public int getImageId() { return imageId; }
}

第二步:编写列表项布局

xml 复制代码
<!-- fruit_item.xml -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="12dp">

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="60dp"
        android:layout_height="60dp" />

    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="12dp"
        android:textSize="16sp" />

</LinearLayout>

第三步:自定义适配器

java 复制代码
public class FruitAdapter extends ArrayAdapter<Fruit> {
    private int resourceId;

    public FruitAdapter(Context context, int resourceId, List<Fruit> objects) {
        super(context, resourceId, objects);
        this.resourceId = resourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Fruit fruit = getItem(position);
        ViewHolder holder;

        if (convertView == null) {
            convertView = LayoutInflater.from(getContext())
                    .inflate(resourceId, parent, false);
            holder = new ViewHolder();
            holder.image = convertView.findViewById(R.id.fruit_image);
            holder.name = convertView.findViewById(R.id.fruit_name);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.image.setImageResource(fruit.getImageId());
        holder.name.setText(fruit.getName());
        return convertView;
    }

    static class ViewHolder {
        ImageView image;
        TextView name;
    }
}

第四步:在 Activity 中绑定

java 复制代码
ListView listView = findViewById(R.id.list_view);
FruitAdapter adapter = new FruitAdapter(this, R.layout.fruit_item, fruitList);
listView.setAdapter(adapter);

// 设置列表项点击事件
listView.setOnItemClickListener((parent, view, position, id) -> {
    Fruit fruit = fruitList.get(position);
    Toast.makeText(this, "你点击了:" + fruit.getName(), Toast.LENGTH_SHORT).show();
});

3.6 RecyclerView ------ 更强大的列表

RecyclerView 是 ListView 的升级版,Google 官方推荐使用。相比 ListView,它:

  • 强制使用 ViewHolder 模式,性能更好
  • 支持线性列表、网格、瀑布流等多种布局
  • 内置条目动画支持
  • 更灵活的局部刷新机制
java 复制代码
// RecyclerView 的基本使用
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));  // 线性布局
recyclerView.setAdapter(new FruitRecyclerAdapter(fruitList));

3.7 Toast ------ 轻量提示

Toast 是一个纯代码创建的控件,无需在 XML 中声明。

java 复制代码
Toast.makeText(context, "提示文字", Toast.LENGTH_SHORT).show();
时长常量 显示时间
Toast.LENGTH_SHORT 约 2 秒
Toast.LENGTH_LONG 约 3.5 秒

3.8 CheckBox 与 RadioButton

xml 复制代码
<!-- 复选框 -->
<CheckBox
    android:id="@+id/agree"
    android:text="我同意用户协议" />

<!-- 单选按钮(需配合 RadioGroup) -->
<RadioGroup
    android:orientation="horizontal">
    <RadioButton android:text="男" />
    <RadioButton android:text="女" />
</RadioGroup>

3.9 Switch(开关)

xml 复制代码
<Switch
    android:id="@+id/switch_wifi"
    android:text="Wi-Fi"
    android:checked="true" />

设置监听:

java 复制代码
Switch sw = findViewById(R.id.switch_wifi);
sw.setOnCheckedChangeListener((buttonView, isChecked) -> {
    if (isChecked) {
        // 开启
    } else {
        // 关闭
    }
});

3.10 SeekBar(滑动条)

xml 复制代码
<SeekBar
    android:id="@+id/progress"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:max="100"
    android:progress="50" />

四、ViewHolder 性能优化详解

在 ListView 或 RecyclerView 的使用中,ViewHolder 模式是必须掌握的性能优化技巧。

为什么需要优化?

findViewById() 会遍历整个 View 树来查找控件,是一个非常耗时 的操作。当用户快速滚动列表时,如果每个 item 都重新执行 findViewById(),就会导致界面卡顿。

ViewHolder 的工作原理

复制代码
                      ┌─────────────────┐
                      │   ListView 滑动  │
                      └────────┬────────┘
                               │
              ┌────────────────┼────────────────┐
              ▼                ▼                ▼
     ┌────────────┐   ┌────────────┐   ┌────────────┐
     │  Item A    │   │  Item B    │   │  Item C    │
     │  (可见)    │   │  (可见)    │   │  (可见)    │
     └────────────┘   └────────────┘   └────────────┘
                               │
              滑出屏幕的 Item 被回收为 convertView
                               │
                               ▼
                    新的 Item 复用 convertView
                     无需重新 inflate 布局

核心代码逻辑:

java 复制代码
if (convertView == null) {
    // 没有可复用的 View → 创建新的,并缓存控件引用
    convertView = inflater.inflate(resourceId, parent, false);
    holder = new ViewHolder();
    holder.text = convertView.findViewById(R.id.text);  // 仅第一次执行
    convertView.setTag(holder);  // 将 ViewHolder 绑定到 View
} else {
    // 有可复用的 View → 直接取出缓存的控件引用
    holder = (ViewHolder) convertView.getTag();  // 瞬间取出
}

性能对比:

方式 每次滑动 流畅度
不用 ViewHolder 重新 findViewById + 重新 inflate 卡顿
复用 convertView 重新 findViewById(但不用 inflate) 一般
ViewHolder 模式 直接从 Tag 取出引用 流畅

五、常见事件监听总结

监听器 适用控件 触发时机
View.OnClickListener Button、ImageView 等 点击
View.OnLongClickListener 大部分控件 长按
View.OnTouchListener 大部分控件 触摸
AdapterView.OnItemClickListener ListView 等 点击列表项
CompoundButton.OnCheckedChangeListener CheckBox、Switch 选中状态改变
SeekBar.OnSeekBarChangeListener SeekBar 进度改变
TextWatcher EditText 文字内容改变

六、总结

本文从零开始,介绍了 Android 开发中最核心的 UI 基础知识:

知识模块 核心内容
四大布局 LinearLayout、RelativeLayout、ConstraintLayout、FrameLayout
核心属性 match_parent/wrap_content、dp/sp、margin/padding、gravity
基础控件 TextView、EditText、Button、ImageView
列表控件 ListView + 自定义 Adapter + ViewHolder 优化
交互控件 CheckBox、RadioButton、Switch、SeekBar
事件处理 点击、长按、状态改变、文本变化等监听器

掌握了这些内容,你就具备了独立搭建 Android App 界面的能力。后续可以进一步学习 Material Design、自定义 View、Jetpack Compose 等更高级的 UI 开发技术。


相关推荐
帅次18 小时前
Android 高级工程师面试:Java 基础知识 近1年高频追问 22 题
android·java·面试
私人珍藏库19 小时前
[Android] zip解压缩管理-全格式压缩包一键解压+打包
android·app·生活·工具·多功能
雨白20 小时前
C语言:动态内存分配
android
Android-Flutter20 小时前
android compose 自定义Painter绘制图形 使用
android·kotlin·compose
我是一颗柠檬20 小时前
【Java项目技术亮点】覆盖索引与索引下推优化
android·java·开发语言
vigor5121 天前
MySQL通过Mango实现分库分表
android·数据库·mysql
阿pin1 天前
Android随笔-Zygote中fork究竟是什么?
android·zygote·fork
Go-higher1 天前
DriverTest 驾考知识卡片学习助手 —— 一款基于 Jetpack Compose 的现代 Android 学习APP
android·学习
安卓修改大师1 天前
安卓修改大师APK控件修改实战教程
android