一、Text
Text 遵循 Material Design 设计规范,如无需使用 Material Design 可以使用更底层的 BasicText 组件。
Text 函数如下所示:
@Composable
fun Text(
text: String, // 显示的文本
modifier: Modifier = Modifier, // 修饰符
color: Color = Color.Unspecified, // 文本颜色
fontSize: TextUnit = TextUnit.Unspecified, // 文字大小
fontStyle: FontStyle ?= null, // 字体样式
fontWeight: FontWeight ?= null, // 文本粗细
fontFamily: FontFamily ?= null, // 文本字体
letterSpacing: TextUnit = TextUnit.Unspecified, // 文本间距
textDecoration: TextDecoration ?= null, // 文本装饰
textAlign: TextAlign ?= null, // 文本对齐方式
lineHeight: TextUnit = TextUnit.Unspecified, // 文本行高
overflow: TextOverflow = TextOverflow.Clip, // 文本溢出效果
softWrap: Boolean = true, // 文本是否能换行
maxLines: Int = Int.MAX_VALUE, // 文本最多几行
onTextLayout: (TextLayoutResult) -> Unit = {}, // 文本变化回调
style: TextStyle = LocalTextStyle.current // 文本样式
)
Text 一般使用方法如下:
Text(text = "Hello World")
Text(text = stringResource(R.string.hello))
二、AnnotatedString
AnnotatedString 可以在一段文字中突出显示指定文本,例如突出显示网址、电话、邮箱等。
buildAnnotatedString
用于构建 AnnotatedStringwithStyle
用于指定文本样式SpanStyle
用于描述文本样式ParagraphStyle
用于描述段落样式append
用于添加文本
Text(
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 20.sp)) {
append("你好,世界")
}
append("\n")
withStyle(style = ParagraphStyle(lineHeight = 24.sp)) {
append("你好,这里展示的是 AnnotatedString")
}
append("\n")
withStyle(style = SpanStyle(
fontWeight = FontWeight.Bold,
textDecoration = TextDecoration.Underline,
color = Color.Blue
)) {
append("我不是罗大锤")
}
}
)
SpanStyle 与 ParagraphStyle 的样式设置优先级高于 TextStyle
三、ClickedText
ClickedText 是一种可以点击的文本组件,可以响应用户对文本的点击并返回点击的位置。
可以组合 AnnotatedString 在点击后响应不同的事件。
修改上一小节 AnnotatedString 代码:
val annotatedText = buildAnnotatedString {
...
// 在文本 “我不是罗大锤” 前后添加标签
pushStringAnnotation(
tag = "URL",
annotation = "https://luodachui.cn"
)
withStyle(style = SpanStyle(
fontWeight = FontWeight.Bold,
textDecoration = TextDecoration.Underline,
color = Color.Blue
)) {
append("我不是罗大锤")
}
// 添加标签
pop()
}
ClickableText(
text = annotatedText,
onClick = { offset ->
// 获取被点击区域 tag 为 URL 的 annotation
annotatedText.getStringAnnotations(
tag = "URL",
start = offset,
end = offset
).firstOrNull()?.let { annotation ->
// 打开 URL
openURL(annotation.item)
}
}
)
四、SelectionContainer
被 SelectionContainer 包裹的文字可以被复制。
SelectionContainer {
Text("我是可被复制的")
}
五、TextField
TextField 遵循 Material Design 设计规范,如无需使用 Material Design 可以使用更底层的 BasicTextField 组件。
TextField 函数如下所示:
@Composable
fun TextField(
value: TextFieldValue, // 显示的文本
onValueChange: (TextFieldValue) -> Unit, // 文本变化回调
modifier: Modifier = Modifier, // 修饰符
enabled: Boolean = true, // 是否启用
readOnly: Boolean = false, // 是否只读
textStyle: TextStyle = LocalTextStyle.current, // 输入框文本样式
label: @Composable (() -> Unit)? = null, // 输入框标签
placeholder: @Composable (() -> Unit)? = null, // 占位符
leadingIcon: @Composable (() -> Unit)? = null, // 输入框开头图标
trailingIcon: @Composable (() -> Unit)? = null, // 输入框末尾图标
isError: Boolean = false, // 输入框当前内容是否有误(输入框样式变为错误颜色)
visualTransformation: VisualTransformation = VisualTransformation.None, // 文本视觉(PasswordVisualTransformation 密码文本)
keyboardOptions: KeyboardOptions = KeyboardOptions.Default, // 软键盘选项
keyboardActions: KeyboardActions = KeyboardActions(), // 输入服务发出 IME 时,回调被调用
singleLine: Boolean = false, // 是否单行
maxLines: Int = Int.MAX_VALUE, // 最大行数
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, // 监听组件状态
shape: Shape =
MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize), // 输入框外观
colors: TextFieldColors = TextFieldDefaults.textFieldColors() // 输入框颜色组
)
TextField 一般使用方法如下:
var name by remember { mutableStateOf("") }
TextField(
value = name,
onValueChange = {
name = it
},
label = {
Text("姓名")
}
)
六、OutlinedTextField
OutlinedTextField 遵循 Material Design 设计规范,相比 TextField 默认带有一个边框。
@Composable
fun init() {
var text by remember { mutableStateOf("") }
OutlinedTextField(
value = text,
onValueChange = {
text = it
},
label = {
Text("姓名")
}
)
}
七、BasicTextField
BasicTextField 是一个低级别的组件,相比 TextField 与 OutlinedTextField 拥有更多的自定义效果。
BasicTextField 关键的一个参数是最后的 decorationBox:
fun BasicTextField(
...
decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
@Composable { innerTextField -> innerTextField() }
)
该参数回调了一个 innerTextField 函数供我们使用,这个函数的作用是定义一个文字的输入入口,当你自定义好了一个输入框界面,需要在相应的地方调用 innerTextField
函数来创建一个输入框。
var text by remember { mutableStateOf("") }
BasicTextField(
value = text,
onValueChange = {
text = it
},
decorationBox = { innerTextField ->
Column(
modifier = Modifier
.background(Color.LightGray)
.height(40.dp)
.fillMaxWidth()
) {
innerTextField()
}
},
textStyle = MaterialTheme.typography.h5
)