Android UI入门:控件与布局

文章目录

  • [Android UI入门:控件与布局](#Android UI入门:控件与布局)
    • [1. 引入:如何编写程序界面?](#1. 引入:如何编写程序界面?)
      • [1.1 Android的界面开发方式](#1.1 Android的界面开发方式)
      • [1.2 基本流程](#1.2 基本流程)
    • [2. 常用控件](#2. 常用控件)
      • [2.1 TextView(显示文本)](#2.1 TextView(显示文本))
      • [2.2 EditText(输入框)](#2.2 EditText(输入框))
      • [2.3 Button(按钮)](#2.3 Button(按钮))
      • [2.4 ImageView(显示图片)](#2.4 ImageView(显示图片))
      • [2.5 ProgressBar(进度条)](#2.5 ProgressBar(进度条))
    • [3. 四种基本布局](#3. 四种基本布局)
      • [3.1 LinearLayout(线性布局)](#3.1 LinearLayout(线性布局))
      • [3.2 RelativeLayout(相对布局)](#3.2 RelativeLayout(相对布局))
      • [3.3 FrameLayout(帧布局)](#3.3 FrameLayout(帧布局))
      • [3.4 ConstraintLayout(约束布局)](#3.4 ConstraintLayout(约束布局))
      • [3.5 布局对比](#3.5 布局对比)
    • [4. 创建自定义控件](#4. 创建自定义控件)
      • [4.1 自定义控件的方式](#4.1 自定义控件的方式)
      • [4.2 组合控件:标题栏](#4.2 组合控件:标题栏)

Android UI入门:控件与布局

1. 引入:如何编写程序界面?

1.1 Android的界面开发方式

Android提供了两种方式来创建界面:

方式 说明 优缺点
XML布局文件 在res/layout目录下编写XML 可视化,结构清晰,解耦
Java代码动态创建 在Activity中用代码创建控件 灵活,适合动态界面

推荐方式:优先使用XML布局文件,Java代码只做逻辑控制。

1.2 基本流程

复制代码
1. 在 res/layout 下创建 XML 布局文件
2. 在 XML 中定义控件(TextView、Button等)
3. 在 Activity 中用 setContentView(R.layout.xxx) 加载布局
4. 在 Java 中用 findViewById() 获取控件
5. 设置控件的事件监听

2. 常用控件

2.1 TextView(显示文本)

xml 复制代码
<TextView
    android:id="@+id/tv_hello"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    android:textSize="18sp"
    android:textColor="#333333"
    android:textStyle="bold" />
属性 说明
text 显示的文本
textSize 字号(推荐用sp)
textColor 颜色(#RRGGBB或#AARRGGBB)
textStyle normal/bold/italic
gravity 对齐方式(center/left/right)
maxLines 最大行数,超出显示...
android:ellipsize="end" 超出显示省略号

2.2 EditText(输入框)

xml 复制代码
<EditText
    android:id="@+id/et_username"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="请输入用户名"
    android:inputType="text"
    android:maxLines="1" />
属性 说明
hint 提示文字(输入后消失)
inputType 输入类型(text/number/password/phone)
maxLines 最大行数
text 默认文本

inputType常用值

说明
text 普通文本
textPassword 密码(隐藏)
number 数字键盘
phone 电话键盘
textEmailAddress 邮箱键盘
java 复制代码
// 在代码中获取输入内容
EditText etUsername = findViewById(R.id.et_username);
String username = etUsername.getText().toString();

2.3 Button(按钮)

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

设置点击事件(4种方式)

方式1:匿名内部类(最常用)

java 复制代码
Button btn = findViewById(R.id.btn_submit);
btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 处理点击
    }
});

方式2:实现接口

java 复制代码
public class MainActivity extends Activity implements View.OnClickListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button btn = findViewById(R.id.btn_submit);
        btn.setOnClickListener(this);
    }
    
    @Override
    public void onClick(View v) {
        // 处理点击
    }
}

方式3:XML中指定方法(不推荐)

xml 复制代码
<Button android:onClick="submit" />
java 复制代码
public void submit(View view) {
    // 处理点击
}

方式4:Lambda(需要Java 8+)

java 复制代码
btn.setOnClickListener(v -> {
    // 处理点击
});

2.4 ImageView(显示图片)

xml 复制代码
<ImageView
    android:id="@+id/iv_avatar"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:src="@drawable/avatar"
    android:scaleType="centerCrop" />
属性 说明
src 图片资源(放在drawable目录下)
scaleType 缩放方式(centerCrop/fitXY/center)
background 背景(也可以是图片)

2.5 ProgressBar(进度条)

xml 复制代码
<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="visible" />
java 复制代码
// 隐藏
progressBar.setVisibility(View.GONE);
// 显示
progressBar.setVisibility(View.VISIBLE);
属性 说明
visibility visible(显示)/ invisible(隐藏占空间)/ gone(隐藏不占空间)

3. 四种基本布局

3.1 LinearLayout(线性布局)

特点:子控件按水平或垂直方向线性排列。

xml 复制代码
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮1"
        android:layout_weight="1" />
        
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮2"
        android:layout_weight="2" />
        
</LinearLayout>

重要属性

属性 说明
orientation vertical/horizontal
gravity 控件整体的对齐方式
layout_gravity 单个控件在父布局中的对齐方式
layout_weight 权重,按比例分配剩余空间

layout_weight详解

xml 复制代码
<!-- 平均分配宽度 -->
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent">
    <Button android:layout_width="0dp" android:layout_weight="1" />
    <Button android:layout_width="0dp" android:layout_weight="1" />
    <Button android:layout_width="0dp" android:layout_weight="1" />
</LinearLayout>

3.2 RelativeLayout(相对布局)

特点:控件相对于父布局或其他控件进行定位。

xml 复制代码
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <!-- 相对于父布局定位 -->
    <Button
        android:id="@+id/btn_center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="居中"
        android:layout_centerInParent="true" />
        
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="左上角"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true" />
        
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="在btn_center下方"
        android:layout_below="@id/btn_center"
        android:layout_centerHorizontal="true" />
        
</RelativeLayout>

常用属性

属性 说明
layout_centerInParent 在父布局中居中
layout_centerHorizontal 水平居中
layout_centerVertical 垂直居中
layout_alignParentTop 与父布局顶部对齐
layout_alignParentBottom 与父布局底部对齐
layout_alignParentLeft 与父布局左边对齐
layout_alignParentRight 与父布局右边对齐
layout_above 在指定控件上方
layout_below 在指定控件下方
layout_toLeftOf 在指定控件左侧
layout_toRightOf 在指定控件右侧
layout_alignTop 与指定控件顶部对齐
layout_alignBottom 与指定控件底部对齐

3.3 FrameLayout(帧布局)

特点:所有控件默认叠放在左上角,后添加的覆盖前面的。

xml 复制代码
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/background" />
        
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="浮在图片上"
        android:textColor="#FFFFFF"
        android:layout_gravity="center" />
        
</FrameLayout>
属性 说明
layout_gravity 控件的对齐方式(在FrameLayout中才有意义)

适用场景

  • 加载中动画
  • 图片上的文字
  • 多个视图切换(如Fragment容器)

3.4 ConstraintLayout(约束布局)

特点:通过约束关系定位控件,减少了布局嵌套,性能更好。

xml 复制代码
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <Button
        android:id="@+id/btn_center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="居中"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />
        
    <Button
        android:id="@+id/btn_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="右侧"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
        
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="在btn_center下方"
        app:layout_constraintTop_toBottomOf="@id/btn_center"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
        
</androidx.constraintlayout.widget.ConstraintLayout>

常用约束属性

属性 说明
layout_constraintStart_toStartOf 左边与目标左边对齐
layout_constraintEnd_toEndOf 右边与目标右边对齐
layout_constraintTop_toTopOf 上边与目标上边对齐
layout_constraintBottom_toBottomOf 下边与目标下边对齐
layout_constraintStart_toEndOf 左边在目标右边
layout_constraintTop_toBottomOf 上边在目标下边
layout_constraintHorizontal_chainStyle 水平链条样式
layout_constraintVertical_chainStyle 垂直链条样式

推荐:ConstraintLayout是Google官方推荐的主流布局。

3.5 布局对比

布局 特点 适用场景
LinearLayout 线性排列,简单 简单列表、表单
RelativeLayout 相对定位 复杂布局、居中
FrameLayout 层叠覆盖 浮层、占位
ConstraintLayout 灵活约束 所有场景(推荐)

4. 创建自定义控件

4.1 自定义控件的方式

方式 说明 适用场景
组合控件 将多个控件组合成一个新控件 标题栏、列表项
继承控件 继承现有控件,添加新功能 自定义EditText
完全自绘 继承View,绘制图形 自定义图表

4.2 组合控件:标题栏

步骤1 :创建布局title_bar.xml

xml 复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="#3F51B5"
    android:gravity="center_vertical"
    android:orientation="horizontal">
    
    <Button
        android:id="@+id/btn_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@null"
        android:text="返回"
        android:textColor="#FFFFFF" />
        
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="标题"
        android:textColor="#FFFFFF"
        android:textSize="18sp" />
        
</LinearLayout>

步骤2 :创建自定义控件类TitleBar.java

java 复制代码
public class TitleBar extends LinearLayout {
    private Button btnBack;
    private TextView tvTitle;
    
    public TitleBar(Context context) {
        this(context, null);
    }
    
    public TitleBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }
    
    private void init(Context context, AttributeSet attrs) {
        // 加载布局
        LayoutInflater.from(context).inflate(R.layout.title_bar, this);
        
        btnBack = findViewById(R.id.btn_back);
        tvTitle = findViewById(R.id.tv_title);
        
        // 处理自定义属性
        if (attrs != null) {
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TitleBar);
            String title = ta.getString(R.styleable.TitleBar_title);
            if (title != null) {
                tvTitle.setText(title);
            }
            ta.recycle();
        }
        
        // 返回按钮点击事件
        btnBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取上下文,销毁当前Activity
                if (getContext() instanceof Activity) {
                    ((Activity) getContext()).finish();
                }
            }
        });
    }
    
    // 设置标题
    public void setTitle(String title) {
        tvTitle.setText(title);
    }
    
    // 设置返回按钮点击监听
    public void setBackListener(OnClickListener listener) {
        btnBack.setOnClickListener(listener);
    }
}

步骤3 :添加自定义属性res/values/attrs.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TitleBar">
        <attr name="title" format="string" />
    </declare-styleable>
</resources>

步骤4:在布局中使用

xml 复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <!-- 使用自定义控件 -->
    <com.example.myapp.TitleBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:title="个人中心" />
        
    <!-- 其他内容 -->
    
</LinearLayout>

一句话总结:UI开发就是选择合适的控件和布局,通过Adapter绑定数据,让用户看到漂亮的界面并与之交互。