theme: channing-cyan
Text控件的相关API说明
Compose中的Text就等价于Android原生中的TextView,API也比较简单: fun Text( text: String, // 文字内容,可以直接传递字符串,也可以使用stringResource(id = R.string.hello)来指定 modifier: Modifier = Modifier, // 修饰符,可以指定宽高,背景,点击事件等。 color: Color = Color.Unspecified, // 文字颜色 fontSize: TextUnit = TextUnit.Unspecified, // 文字大小 fontStyle: FontStyle? = null, // 文字样式,比如斜体 fontWeight: FontWeight? = null, // 字体宽度,比如粗体 fontFamily: FontFamily? = null, // 字体样式,比如SansSerif,Serif等 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 // 设置Style,类似TextView的style )
TextStyle的API,内容跟Text里面的大部分相同,具体可以查看相关API,这里有个点需要提一下: Text不能垂直居中,要想垂直居中,可以在外面包一层父View,比如Box。
基础示例
我们来个小Demo @Composable fun TextDemo() { val text = "this is compose text demo, which likes TextView in android native xml layout" Text( text = text, // 文字 color = Color.Green, // 字体颜色 fontSize = 16.sp, // 字体大小 fontStyle = FontStyle.Italic, // 斜体 fontWeight = FontWeight.Bold, // 粗体 textAlign = TextAlign.Center, // 对齐方式: 居中对齐 modifier = Modifier.width(300.dp), // 指定宽度为300dp maxLines = 2, // 最大行数 overflow = TextOverflow.Ellipsis, // 文字溢出后就裁剪 softWrap = true, // 文字过长时是否换行 textDecoration = TextDecoration.Underline, // 文字装饰,这里添加下划线 ) }
效果如下:
然后我们加上字体样式: fontFamily = FontFamily.Cursive, // 字体样式
效果如下:
我们再加上行高和字符间距: lineHeight = 40.sp, // 行高40sp letterSpacing = 5.sp // 字符间距5sp
效果如下:
富文本
使用原生的TextView如果想要实现富文本,需要使用Spanable,而且需要计算文字的下标,非常麻烦,Compose的就相当好用了。
1 使用SpanStyle来实现富文本
API如下: class SpanStyle( val color: Color = Color.Unspecified, // 文字颜色 val fontSize: TextUnit = TextUnit.Unspecified, // 文字大小 val fontWeight: FontWeight? = null, // 字体粗细,比如粗体 val fontStyle: FontStyle? = null, // 文字样式,比如斜体 val fontSynthesis: FontSynthesis? = null, // 指定的字体找不到时,所采用的策略 val fontFamily: FontFamily? = null, // 字体样式,比如Serif val fontFeatureSettings: String? = null, // 字体的排印设置,可以取CSS中font-feature-settings的值 val letterSpacing: TextUnit = TextUnit.Unspecified, // 字符间距 val baselineShift: BaselineShift? = null, // 文字举例baseline的向上偏移量 val textGeometricTransform: TextGeometricTransform? = null, // 用于几何变换,比如缩放、倾斜等 val localeList: LocaleList? = null, // 国际化相关符号列表 val background: Color = Color.Unspecified, // 背景色 val textDecoration: TextDecoration? = null, // 装饰,比如下划线 val shadow: Shadow? = null // 阴影 )
直接看Demo: ``` @Composable fun TextDemo2() { Text(buildAnnotatedString { // 使用白色背景,红色字体,18sp,Monospace字体来绘制"Hello " (注意后面有个空格) withStyle(style = SpanStyle(color = Color.Red, background = Color.White, fontSize = 18.sp, fontFamily = FontFamily.Monospace)) { append("Hello ") } // 正常绘制"World" append("World ") // 使用黄色背景,绿色字体,18sp,Serif字体,W900粗体来绘制"Click" withStyle(style = SpanStyle(color = Color.Green, background = Color.Yellow, fontSize = 30.sp, fontFamily = FontFamily.Serif, fontWeight = FontWeight.W900)) { append("Click") } // 正常绘制" Me" (注意前面有个空格) append(" Me")
// 添加阴影及几何处理
withStyle(
style = SpanStyle(
color = Color.Yellow,
background = Color.White,
baselineShift = BaselineShift(1.0f), // 向BaseLine上偏移10
textGeometricTransform = TextGeometricTransform(scaleX = 2.0F, skewX = 0.5F), // 水平缩放2.0,并且倾斜0.5
shadow = Shadow(color = Color.Blue, offset = Offset(x = 1.0f, y = 1.0f), blurRadius = 10.0f) // 添加音阴影和模糊处理
)
) {
append(" Effect")
}
})
} ``` 其中buildAnnotatedString()可以理解为构建了一个作用域,在该作用域内可以使用withStyle(style)来指定文字格式,效果如下:
2 使用ParagraphStyle来实现段落
API如下: class ParagraphStyle constructor( val textAlign: TextAlign? = null, // 对齐方式 val textDirection: TextDirection? = null, // 文字方向 val lineHeight: TextUnit = TextUnit.Unspecified, //行高 val textIndent: TextIndent? = null // 缩进方式 )
直接看Demo: ``` @Composable fun TextDemo3() { Text(buildAnnotatedString { // 指定对齐方式为Start,通过textIndent指定第一行每段第一行缩进32sp,其余行缩进8sp withStyle(style = ParagraphStyle(textAlign = TextAlign.Start, textIndent = TextIndent(firstLine = 32.sp, restLine = 8.sp))) {
// 第一段,因为只有一行,所以直接缩进32sp
withStyle(style = SpanStyle(color = Color.Red)) {
append("Hello, this is first paragraph\n")
}
// 第二段(第一行会缩进32sp,后续每行会缩进8sp)
withStyle(style = SpanStyle(color = Color.Green, fontWeight = FontWeight.Bold)) {
append("Hello, this is second paragraph,very long very long very long very long very long very long very long very long very long very long\n")
}
// 第三段,因为只有一行,所以直接缩进32sp
append("Hello, this is third paragraph\n")
}
})
} ``` 效果如下:
交互
传统的Android的TextView可以实现选中/不可选中,但是却很难实现部分可选中,部分不可选中;传统的TextView可以设置点击事件,但是很难实现获取点击文字的位置,这些在Compose中都不是事。
1 可选中和不可选中
我们可以直接使用SelectionContainer来包括可以选中的文本,使用DisableSelection来包括不可选中的文本,eg:
``` @Composable fun TextDemo4() { // 设置可选区域 SelectionContainer { // Column等价于竖直的LinearLayout Column { Text(text = "可以选中我,可以选中我,可以选中我")
// 设置不可选区域
DisableSelection {
Text(text = "选不中我,选不中我,选不中")
}
// 位于可选区域内,可选
Text(text = "可以选中我,可以选中我,可以选中我")
}
}
} ``` 效果如下:
2 单个文字响应点击事件
我们可以直接使用ClickableText来实现点个文字的点击效果,API如下: fun ClickableText( text: AnnotatedString, // 传入的文字,这里必须传入AnnotatedString modifier: Modifier = Modifier, // 修饰符 style: TextStyle = TextStyle.Default, // 文本Style softWrap: Boolean = true, // 文本长度过长时,是否换行 overflow: TextOverflow = TextOverflow.Clip, // 文字超出显示范围的处理方式,默认Clip,就是不显示 maxLines: Int = Int.MAX_VALUE, // 最大行数 onTextLayout: (TextLayoutResult) -> Unit = {}, // 布局发生变化的回调 onClick: (Int) -> Unit // 点击事件,参数为点击文字的下标 )
Demo如下: @Composable fun TextDemo5(context: Context) { ClickableText(text = AnnotatedString("请点击我"), onClick = { index -> Toast.makeText(context, "点击位置:$index", Toast.LENGTH_SHORT).show() }) }
效果如下:
如果要给整个Text()设置点击事件,直接使用Modifier.clickable{}即可。
3 给指定文字添加注解(超链接)
我们可以使用pushStringAnnotation()和pop()函数对来给指定文字添加注解,如下:
``` @Composable fun TextDemo6(context: Context) {
// 构建注解文本
val url_tag = "article_url";
val articleText = buildAnnotatedString {
append("点击")
// pushStringAnnotation()表示开始添加注解,可以理解为构造了一个<tag,annotation>的映射
pushStringAnnotation(tag = url_tag, annotation = "https://devloper.android.com")
// 要添加注解的文本为"展示Android官网"
withStyle(style = SpanStyle(color = Color.Blue, fontWeight = FontWeight.Bold)) {
append("展示Android官网")
}
// pop()表示注解结束
pop()
}
// 构造可点击文本
ClickableText(text = articleText, onClick = { index ->
// 根据tag取出annotation并打印
articleText.getStringAnnotations(tag = url_tag, start = index, end = index).firstOrNull()?.let { annotation ->
Toast.makeText(context, "点击了:${annotation.item}", Toast.LENGTH_SHORT).show()
}
})
} ``` 效果如下:
Demo可在这里下载: https://gitee.com/lloydfinch/compose-text-demo
当然,Text的用法远不止此,更多的用法可以查看官方API即可。