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 | 电话号码 |
| textUri | URL |
监听输入
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 组件:
- TextView:显示文本,支持富文本和自动链接
- EditText:接收用户输入,支持多种输入类型
- Button:触发点击事件,支持多种样式
- ImageView:显示图片,支持多种缩放模式
- RecyclerView:高效的列表组件
- CardView:卡片容器
- ProgressBar:进度指示
- Dialog:对话框
- Toast/Snackbar:消息提示
下一章将学习 Fragment 组件,理解如何构建灵活的多页面界面。