Skip to content

文本与输入 (Text)

源:Compose 文本

文本是 UI 中最基础的元素。Compose 提供了 Text用于显示文本,以及 TextField 用于用户输入。

1. 显示文本 (Text)

基础样式

kotlin
Text(
    text = "Hello World",
    color = Color.Blue,
    fontSize = 30.sp,
    fontWeight = FontWeight.Bold,
    fontStyle = FontStyle.Italic,
    textAlign = TextAlign.Center,
    modifier = Modifier.fillMaxWidth()
)

富文本 (AnnotatedString)

如果要在同一行文本中应用多种样式(例如“点击这里注册”),可以使用 buildAnnotatedString

kotlin
val annotatedString = buildAnnotatedString {
    append("请阅读并同意 ")
    
    // 压入样式
    withStyle(style = SpanStyle(color = Color.Blue, textDecoration = TextDecoration.Underline)) {
        pushStringAnnotation(tag = "URL", annotation = "https://privacy.com")
        append("隐私政策")
        pop() // 记得弹出
    }
}
kotlin
ClickableText(
    text = annotatedString,
    onClick = { offset ->
        annotatedString.getStringAnnotations(tag = "URL", start = offset, end = offset)
            .firstOrNull()?.let { annotation ->
                Log.d("Link", "点击了链接: ${annotation.item}")
            }
    }
)

2. 文本输入 (TextField)

Material Design 提供了两种风格的输入框:

  • TextField: 默认风格(带背景填充)。
  • OutlinedTextField: 轮廓风格(带边框)。

状态提升

输入框是无状态的,必须将 valueonValueChange 提升到父组件管理。

基础用法

kotlin
var text by remember { mutableStateOf("") }

OutlinedTextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("用户名") },
    placeholder = { Text("请输入用户名") },
    leadingIcon = { Icon(Icons.Default.Person, null) },
    trailingIcon = { 
        if (text.isNotEmpty()) {
            IconButton(onClick = { text = "" }) {
                Icon(Icons.Default.Clear, null)
            }
        }
    },
    singleLine = true
)

键盘操作与密码

使用 visualTransformation 处理密码显示,使用 keyboardOptionskeyboardActions 控制软键盘。

kotlin
var password by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) }

OutlinedTextField(
    value = password,
    onValueChange = { password = it },
    label = { Text("密码") },
    // 1. 密码隐藏/显示逻辑
    visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
    trailingIcon = {
        val image = if (passwordVisible) Icons.Filled.Visibility else Icons.Filled.VisibilityOff
        IconButton(onClick = { passwordVisible = !passwordVisible }) {
            Icon(image, null)
        }
    },
    // 2. 键盘类型设置
    keyboardOptions = KeyboardOptions(
        keyboardType = KeyboardType.Password,
        imeAction = ImeAction.Done
    ),
    // 3. 键盘动作监听
    keyboardActions = KeyboardActions(
        onDone = { 
            // 隐藏键盘或提交
        }
    )
)

BasicTextField (自定义)

如果您不想使用 Material Design 风格,可以使用 BasicTextField 完全自定义外观(例如搜索栏或验证码输入框)。

kotlin
BasicTextField(
    value = text,
    onValueChange = { text = it },
    decorationBox = { innerTextField ->
        Box(
            Modifier
                .background(Color.LightGray, RoundedCornerShape(8.dp))
                .padding(16.dp)
        ) {
            if (text.isEmpty()) Text("自定义占位符")
            innerTextField() // 必须调用,绘制实际输入内容
        }
    }
)