跳到主要内容

UI 组件

Android 提供了丰富的 UI 组件用于构建用户界面。本章将介绍常用的 UI 控件及其使用方法。

TextView(文本视图)

TextView 用于显示文本内容,是最基础的 UI 组件。

基本使用

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World"
android:textSize="18sp"
android:textColor="#333333" />

常用属性

属性说明示例
text显示的文本"Hello"
textSize文字大小"18sp"
textColor文字颜色"#FF0000" 或 "@color/red"
textStyle文字样式normal, bold, italic
maxLines最大行数2
ellipsize超出时的省略方式end, start, middle, marquee
gravity文字对齐方式center, left, right
lineSpacingExtra行间距"4dp"

代码中设置

val textView = findViewById<TextView>(R.id.tv_title)

textView.text = "新的文本内容"
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20f)
textView.setTextColor(Color.RED)

// 使用 SpannableString 设置富文本
val spannable = SpannableString("红色粗体文字")
spannable.setSpan(ForegroundColorSpan(Color.RED), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
spannable.setSpan(StyleSpan(Typeface.BOLD), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
textView.text = spannable

自动链接

TextView 可以自动识别并链接文本中的 URL、电话、邮箱等:

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="访问 https://www.example.com 或致电 10086"
android:autoLink="web|phone" />

EditText(输入框)

EditText 继承自 TextView,用于接收用户输入。

基本使用

<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"
android:inputType="text"
android:maxLines="1" />

输入类型

inputType 属性决定了键盘类型和输入限制:

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

监听输入

val editText = findViewById<EditText>(R.id.et_username)

// 添加文本变化监听
editText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
// 文本变化前
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
// 文本变化中
Log.d("EditText", "当前输入: $s")
}

override fun afterTextChanged(s: Editable?) {
// 文本变化后
}
})

// 获取输入内容
val input = editText.text.toString()

Button(按钮)

Button 用于触发点击事件。

基本使用

<Button
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="提交"
android:onClick="onSubmitClick" />
// 方式一:XML 中指定 onClick 方法
fun onSubmitClick(view: View) {
Toast.makeText(this, "按钮被点击", Toast.LENGTH_SHORT).show()
}

// 方式二:代码中设置监听器
val button = findViewById<Button>(R.id.btn_submit)
button.setOnClickListener {
Toast.makeText(this, "按钮被点击", Toast.LENGTH_SHORT).show()
}

按钮样式

<!-- 普通按钮 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="普通按钮" />

<!-- 边框按钮 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="边框按钮"
style="@style/Widget.MaterialComponents.Button.OutlinedButton" />

<!-- 文字按钮 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文字按钮"
style="@style/Widget.MaterialComponents.Button.TextButton" />

ImageView(图片视图)

ImageView 用于显示图片。

基本使用

<ImageView
android:id="@+id/iv_photo"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/photo"
android:scaleType="centerCrop"
android:contentDescription="用户头像" />

scaleType 缩放类型

scaleType说明
center居中显示,不缩放
centerCrop等比缩放填满,裁剪多余部分
centerInside等比缩放,确保完整显示
fitCenter等比缩放,居中
fitXY拉伸填满(可能变形)
matrix使用矩阵变换

加载网络图片

使用 Glide 或 Coil 库加载网络图片:

// 使用 Glide
Glide.with(this)
.load("https://example.com/image.jpg")
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.into(imageView)

// 使用 Coil(Kotlin 协程友好)
imageView.load("https://example.com/image.jpg") {
placeholder(R.drawable.placeholder)
error(R.drawable.error)
transformations(CircleCropTransformation())
}

RecyclerView(列表视图)

RecyclerView 是 Android 推荐的列表组件,比 ListView 更灵活高效。

添加依赖

dependencies {
implementation("androidx.recyclerview:recyclerview:1.3.2")
}

布局文件

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

创建 Adapter

// 数据类
data class User(val id: Int, val name: String, val avatar: String)

// ViewHolder
class UserViewHolder(private val binding: ItemUserBinding) :
RecyclerView.ViewHolder(binding.root) {

fun bind(user: User) {
binding.tvName.text = user.name
// 加载头像等
}
}

// Adapter
class UserAdapter(private val users: List<User>) :
RecyclerView.Adapter<UserViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val binding = ItemUserBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return UserViewHolder(binding)
}

override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(users[position])
}

override fun getItemCount() = users.size
}

使用 RecyclerView

val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)

// 设置布局管理器
recyclerView.layoutManager = LinearLayoutManager(this) // 列表
// recyclerView.layoutManager = GridLayoutManager(this, 2) // 网格

// 设置 Adapter
val users = listOf(
User(1, "张三", "avatar1.jpg"),
User(2, "李四", "avatar2.jpg")
)
recyclerView.adapter = UserAdapter(users)

// 添加分割线
recyclerView.addItemDecoration(
DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
)

CardView(卡片视图)

CardView 提供带阴影和圆角的卡片容器。

添加依赖

dependencies {
implementation("androidx.cardview:cardview:1.0.0")
}

使用示例

<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
app:cardUseCompatPadding="true">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="卡片标题"
android:textSize="18sp"
android:textStyle="bold" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="卡片内容描述"
android:layout_marginTop="8dp" />

</LinearLayout>

</androidx.cardview.widget.CardView>

ProgressBar(进度条)

圆形进度条

<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

水平进度条

<ProgressBar
android:id="@+id/progress_horizontal"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="30" />
val progressBar = findViewById<ProgressBar>(R.id.progress_horizontal)
progressBar.progress = 50 // 设置进度
progressBar.incrementProgressBy(10) // 增加进度

Dialog(对话框)

AlertDialog

AlertDialog.Builder(this)
.setTitle("确认删除")
.setMessage("确定要删除这条记录吗?")
.setPositiveButton("删除") { dialog, which ->
// 确认删除
}
.setNegativeButton("取消") { dialog, which ->
dialog.dismiss()
}
.setNeutralButton("稍后提醒") { dialog, which ->
// 稍后提醒
}
.show()

列表对话框

val items = arrayOf("选项一", "选项二", "选项三")

AlertDialog.Builder(this)
.setTitle("请选择")
.setItems(items) { dialog, which ->
Toast.makeText(this, "选择了: ${items[which]}", Toast.LENGTH_SHORT).show()
}
.show()

单选对话框

val items = arrayOf("红色", "绿色", "蓝色")
var selectedIndex = 0

AlertDialog.Builder(this)
.setTitle("选择颜色")
.setSingleChoiceItems(items, selectedIndex) { dialog, which ->
selectedIndex = which
}
.setPositiveButton("确定") { dialog, which ->
Toast.makeText(this, "选择了: ${items[selectedIndex]}", Toast.LENGTH_SHORT).show()
}
.show()

Toast(提示消息)

Toast 用于显示短暂的提示信息。

// 基本用法
Toast.makeText(this, "操作成功", Toast.LENGTH_SHORT).show()

// 自定义位置
val toast = Toast.makeText(this, "自定义位置", Toast.LENGTH_SHORT)
toast.setGravity(Gravity.CENTER, 0, 0)
toast.show()

// 自定义布局
val layout = layoutInflater.inflate(R.layout.custom_toast, null)
val toast = Toast(this)
toast.view = layout
toast.duration = Toast.LENGTH_SHORT
toast.show()

Snackbar(消息条)

Snackbar 是 Material Design 风格的消息提示,比 Toast 更灵活。

// 基本用法
Snackbar.make(binding.root, "操作成功", Snackbar.LENGTH_SHORT).show()

// 带操作按钮
Snackbar.make(binding.root, "已删除", Snackbar.LENGTH_LONG)
.setAction("撤销") {
// 撤销删除
}
.show()

小结

本章介绍了 Android 常用的 UI 组件:

  1. TextView:显示文本,支持富文本和自动链接
  2. EditText:接收用户输入,支持多种输入类型
  3. Button:触发点击事件,支持多种样式
  4. ImageView:显示图片,支持多种缩放模式
  5. RecyclerView:高效的列表组件
  6. CardView:卡片容器
  7. ProgressBar:进度指示
  8. Dialog:对话框
  9. Toast/Snackbar:消息提示

下一章将学习 Fragment 组件,理解如何构建灵活的多页面界面。