Compose Text简单使用
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
基础示例
我们来个小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")
// 要添加注解的文本为"打开本文"
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可在这里下载: gitee.com/lloydfinch/…
当然,Text的用法远不止此,更多的用法可以查看官方API即可。
作者:奔波儿灞取经
链接:https://juejin.cn/post/6981396073952575519
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。