今天不干饭,干下Compose里面Text控件,类似TextView,不过在Compose里Text是一个函数,绘制文本。
基本属性
text: String // 设置文本 modifier: Modifier // 这个很复杂后面单说 color: Color = Color.Unspecified // 字体颜色 fontSize: TextUnit // 字号 fontStyle: FontStyle // 斜体 fontWeight: FontWeight? // 粗细 fontFamily: FontFamily // 字体 letterSpacing: TextUnit // 字间距 sp textDecoration: TextDecoration // 删除线、下划线 textAlign: TextAlign // 对齐方式 lineHeight: TextUnit // 行高 sp overflow: TextOverflow // 文本溢出,默认截取 softWrap: Boolean // 默认true,如果false,overflow为默认时候溢出文本不会截取,而且文本不换行 maxLines: Int // 最大行数 style: TextStyle // 上面的属性最后都会覆盖该对象的属性,所以也可以完全通过该属性来自定义Text
下面我们通过TextView常用的一些操作来介绍Text函数,例如文本的颜色,大小,加粗,斜体,删除线,字体等,这些Text函数都支持。
一个简单使用Text
函数
Text(text = "简单示例")
Text函数有一个重载函数,text属性的类型是AnnotatedString
。这是一个多样式多文本类型的数据对象。简单说,我们一个文本可以不同部分展示不同样式。如下示例
val multiStyleText = buildAnnotatedString { append("红色 加粗 斜体 正常") addStyle(style = SpanStyle(color = Color.Red), start = 0, end = 2) addStyle(style = SpanStyle(fontWeight = FontWeight.Bold), start = 3, end = 5) addStyle(style = SpanStyle(fontStyle = FontStyle.Italic), start = 6, end = 8) } Text(text = multiStyleText)
文字颜色可以通过color
属性配置,在新建工程时候有个theme包
,我们一般颜色资源都是放在该包Color文件中,我们就引用这里的颜色资源即可。
Text( text = "Hello $name!" color = Purple200 )
当然除了使用在Color文件中定义的颜色外,还可以直接调用Color()
函数来设置颜色,这种就类似xml配置中我们直接使用#FFFFFF
来设置颜色。我们已可以引用系统的颜色,例如Color.RED
。
字体大小可以通过fontSize属性配置。这里fontSize为类型为TextUnit,而Compose框架中扩展了Int函数dp、sp,所以我们直接调用即可。
Text( text = "Hello $name!", fontSize = 11.sp )
这里需要特别说明下,在TextUnit中有一个新的单位em,转换公式1em = 16px
。
粗体可通过fontWeight属性配置,该属性类型为FontWeight
,该类支持多种字宽度100-900,我们给字体加粗使用600,700,800,900即可。
Text( text = "Hello $name!", fontWeight = FontWeight.BOLD )
斜体可通过fontStyle
来配置,该属性类型为FontStyle
,而该类为枚举类型,支持正常和斜体。
Text( text = "Hello $name!", fontStyle = FontStyle.Italic )
字间距通过letterSpacing属性配置,这里需要注意的是这里必须使用sp的扩展,不能使用dp。
Text( text = "5sp的字符间距", letterSpacing = 5.sp )
删除线、下划线通过textDecoration属性来配置,该属性类型为TextDecoration
,内部支持LineThrough
和Underline
设置。
Text( text = "删除线", textDecoration = TextDecoration.LineThrough ) Text( text = "下划线", textDecoration = TextDecoration.Underline )
字体设置和xml配置一样都是需要配置fontFamily
属性。JetpackCompose
中也内置了Android系统字体,但是我想一般我们不会使用,毕竟中国都是汉字。下面示例加载本地字体
Text( text = "Baiyu is NB", fontFamily = FontFamily(Font(R.font.abeezee)) )
行高通过lineHeight
属性配置,这里单位同字间距一样也是sp,该属性必须多行文字才会有效果。
Text( text = "行高文本", lineHeight = 30.sp, modifier = Modifier.width(40.dp) // 这里文本太短所以设置宽度为40以达到换行目的,关于Modifier后面单独讲解 )
文本对齐可使用textAlign
属性实现,当然你的文本内容要小于Text的宽度,不然没有效果哦
// 右对齐效果 Text( text = "右对齐文字", textAlign = TextAlign.End, modifier = Modifier.width(200.dp) )
在TextView我们可以设置android:ellipsize="end"
和android:lines="1"
来实现溢出后省略号表示,在Compose中我们可以通过maxLines
和overflow
属性来实现。默认是截取效果。
Text( text = "溢出文字", maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.width(50.dp) )
文本缩进一般用于段落,该属性Text函数没有配置,需要通过textStyle
属性来实现
Text( text = "这是一个段落文本展示了首行缩进效果", modifier = Modifier.width(100.dp), style = TextStyle(textIndent = TextIndent(24.sp)) )
额,我觉得这样称呼这个属性inlineContent
的功能比较贴切,哈哈。该属性类型为Map<String, InlineTextContent>
,使用inlineContext
需要配合上面多样式文本结合使用。下面展示一个图文内容
val inlineContentText = buildAnnotatedString { append("inlineContext展示图文") appendInlineContent("image") appendInlineContent("text") } val inlineContent = mapOf( "image" to InlineTextContent ( placeholder = Placeholder( width = 2.em, height = 2.em, placeholderVerticalAlign = PlaceholderVerticalAlign.AboveBaseline ), children = { Image( // 这里资源是DrawableRes bitmap = ImageBitmap.imageResource(id = R.drawable.acto), contentDescription = null ) } ), "text" to InlineTextContent ( placeholder = Placeholder( width = 2.em, height = 2.em, placeholderVerticalAlign = PlaceholderVerticalAlign.AboveBaseline ), children = { Text(text = "InlineText") } ) ) Text( text = inlineContentText, inlineContent = inlineContent )
话外
学习ComposeUI
,看到一个博客Jetpack Compose - Text文中提到如何单独给上文中的红色字体设置点击事件的API,我想有这个属性就不在是难事了。另外官方也给出了ClickableText函数可以更简单的实现
补充:
这里补充一个官方看到的ClickableText函数,还是蛮实用的。例如文本中含有电话,或者URL连接,用户点击后可以接收事件,然后调用打电话或者打开网址。
@Composable fun DialText(context:Context) { val annotatedText = buildAnnotatedString { append("拨打电话") pushStringAnnotation( tag = "tel", annotation = "15888888888" ) withStyle( style = SpanStyle( color = Color.Blue, fontWeight = FontWeight.Bold ) ) { append("15888888888") } pop() } ClickableText( text = annotatedText, onClick = { offset -> annotatedText.getStringAnnotations(tag = "tel", start = offset, end = offset) .firstOrNull()?.let { annotation -> context.startActivity(Intent().apply { action = Intent.ACTION_DIAL data = Uri.parse("tel:${annotation.item}") }) } } ) }
这个在Compose UI
中还没有发现,Google也没有大神来实现这个效果,以后看到在补上吧。
目前还没有找到设置方法,不过感觉实际不需要了,因为你可以设置文本的宽度,如果超过宽度就按着溢出截取掉就好了。
这个是在官网看到的,主要就是用户是否可以选择文本做复制粘贴操作,默认Text函数设置的文本用户无法通过长按进行选择的,如果要启动,需要外层增加SelectionContainer
,详细可参看用户互动
SelectionContainer { Column { Text("可选择文本") DisableSelection { Text("不可选择") } } }
以上属性都可以通过style
直接自定义实现。通过源码我们可以看到最终Text函数
会调用BasicText函数
并将Text函数
中设置的一些属性参数都通过调用textStyle.merge覆盖TextStyle默认的属性了。
感谢:
Vinay Gaba
推荐:
Google Fonts