首页 / Android 入门教程 / Compose 文本与输入

Android 入门教程

Compose 文本与输入

本教程共 100 篇 · 第 47 篇 · 更新于 2026-07-28 · 约 7 分钟阅读

AndroidAndroid 入门教程Jetpack ComposeTextTextFieldOutlinedTextField文本输入

47. Compose 文本与输入

本节目标:掌握 Text 文本组件的样式配置、TextField 和 OutlinedTextField 输入框的用法,学会富文本、键盘类型设置和输入校验。

Text 文本组件

Text 是最基础的展示组件。先回顾一下基础用法,再看进阶:

@Composable
fun TextExample() {
    Text(
        text = "这是一段文字",
        color = Color.DarkGray,
        fontSize = 16.sp,
        fontWeight = FontWeight.Medium,
        letterSpacing = 0.5.sp,
        lineHeight = 24.sp,
        maxLines = 2,
        overflow = TextOverflow.Ellipsis
    )
}
参数作用常用值
color文字颜色Color.Red / MaterialTheme.colorScheme.onSurface
fontSize字号14.sp ~ 24.sp
fontWeight粗细Normal / Bold / Medium
lineHeight行高通常为字号的 1.5 倍
maxLines最大行数1 / 2
overflow溢出处理Ellipsis(省略号)

富文本 AnnotatedString

一段文字里有多种颜色、大小、样式,用 buildAnnotatedString

@Composable
fun RichTextExample() {
    Text(
        buildAnnotatedString {
            append("普通文字 ")
            withStyle(style = SpanStyle(color = Color.Red, fontWeight = FontWeight.Bold)) {
                append("红色加粗 ")
            }
            withStyle(style = SpanStyle(fontSize = 20.sp)) {
                append("大号字")
            }
        }
    )
}

可点击的链接文本

@Composable
fun ClickableTextExample() {
    val annotatedText = buildAnnotatedString {
        append("同意《")
        pushStringAnnotation(
            tag = "URL",
            annotation = "https://example.com/terms"
        )
        withStyle(SpanStyle(color = Color.Blue)) {
            append("用户协议")
        }
        pop()
        append("》")
    }

    ClickableText(
        text = annotatedText,
        onClick = { offset ->
            annotatedText.getStringAnnotations(
                tag = "URL",
                start = offset,
                end = offset
            ).firstOrNull()?.let { annotation ->
                // 打开链接
                Log.d("Link", annotation.item)
            }
        }
    )
}
Tip
  • 富文本适合做「同意协议」「带链接的说明」等场景。pushStringAnnotation 给一段文字打标签,点击时通过标签取出附加数据。

TextField 输入框

TextField 是基础输入框,对应传统 View 的 EditText。它遵循状态提升原则:值从外部传入,变化通过回调通知外部:

@Composable
fun NameInput() {
    var name by remember { mutableStateOf("") }

    TextField(
        value = name,
        onValueChange = { name = it },
        label = { Text("姓名") },
        singleLine = true
    )
}
Warning
  • TextFieldvalueonValueChange 必须成对出现。如果你只传了 value 不处理 onValueChange,输入框将无法输入—因为状态没更新,Compose 重新渲染时还是旧值。

OutlinedTextField

OutlinedTextField 是带外边框的输入框样式,Material Design 推荐:

@Composable
fun EmailInput() {
    var email by remember { mutableStateOf("") }

    OutlinedTextField(
        value = email,
        onValueChange = { email = it },
        label = { Text("邮箱") },
        placeholder = { Text("请输入邮箱地址") },
        leadingIcon = { Icon(Icons.Default.Email, contentDescription = null) },
        trailingIcon = { Icon(Icons.Default.Clear, contentDescription = "清除") },
        singleLine = true,
        modifier = Modifier.fillMaxWidth()
    )
}
参数作用
label标签(聚焦时浮到上方)
placeholder空内容时的提示文字
leadingIcon输入框前面的图标
trailingIcon输入框后面的图标
singleLine是否单行
enabled是否可编辑

键盘选项

OutlinedTextField(
    value = phone,
    onValueChange = { phone = it },
    label = { Text("手机号") },
    keyboardOptions = KeyboardOptions(
        keyboardType = KeyboardType.Phone,      // 数字键盘
        capitalization = KeyboardCapitalization.None,
        autoCorrect = false,
        imeAction = ImeAction.Done              // 键盘右下角显示「完成」
    ),
    keyboardActions = KeyboardActions(
        onDone = { /* 点击完成时执行 */ }
    )
)

常用 keyboardType

KeyboardType键盘类型
Text普通文本
Number数字
Phone电话号码
Email带有 @ 符号
Password密码(隐藏字符)
UriURL 输入

密码输入框

@Composable
fun PasswordInput() {
    var password by remember { mutableStateOf("") }
    var visible by remember { mutableStateOf(false) }

    OutlinedTextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("密码") },
        singleLine = true,
        visualTransformation = if (visible) VisualTransformation.None
                               else PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
        trailingIcon = {
            IconButton(onClick = { visible = !visible }) {
                Icon(
                    if (visible) Icons.Default.Visibility
                    else Icons.Default.VisibilityOff,
                    contentDescription = "显示/隐藏密码"
                )
            }
        }
    )
}

输入校验

校验通常在 onValueChange 里做:

@Composable
fun ValidatedEmailInput() {
    var email by remember { mutableStateOf("") }
    val isError = remember(email) {
        email.isNotEmpty() && !email.contains("@")
    }

    OutlinedTextField(
        value = email,
        onValueChange = { email = it },
        label = { Text("邮箱") },
        isError = isError,
        supportingText = {
            if (isError) {
                Text("邮箱格式不正确", color = MaterialTheme.colorScheme.error)
            }
        },
        singleLine = true
    )
}
Note
  • isError 让输入框边框变红,supportingText 显示错误提示。校验逻辑用 remember(email) 缓存,只在 email 变化时重新计算。

文本样式对齐

Text(
    text = "居中对齐的多行文字",
    textAlign = TextAlign.Center,
    modifier = Modifier.fillMaxWidth()
)

textAlign 控制多行文本的对齐方式:StartEndCenterJustify

小结

Text 展示文字,AnnotatedString 做富文本,ClickableText 做可点击链接。TextField 和 OutlinedTextField 做输入框,务必成对处理 value 和 onValueChange。用 keyboardOptions 控制键盘类型和动作按钮,用 isError 做校验提示。下一节学习按钮和交互组件。