【原创】Jetpack Compose学习笔记(二)

Jetpack Compose学习笔记(二)

今天不干饭,干下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,我们给字体加粗使用600700800900即可。

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,内部支持LineThroughUnderline设置。

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中我们可以通过maxLinesoverflow属性来实现。默认是截取效果。

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也没有大神来实现这个效果,以后看到在补上吧。

备注:最新看到了这个实现了,有空可以试试,上个连接:Compose——Text跑马灯效果

字符长度限制

目前还没有找到设置方法,不过感觉实际不需要了,因为你可以设置文本的宽度,如果超过宽度就按着溢出截取掉就好了。

补充:文本选择

这个是在官网看到的,主要就是用户是否可以选择文本做复制粘贴操作,默认Text函数设置的文本用户无法通过长按进行选择的,如果要启动,需要外层增加SelectionContainer,详细可参看用户互动

SelectionContainer {
    Column {
        Text("可选择文本")
        DisableSelection {
            Text("不可选择")
        }
    }
}




以上属性都可以通过style直接自定义实现。通过源码我们可以看到最终Text函数会调用BasicText函数并将Text函数中设置的一些属性参数都通过调用textStyle.merge覆盖TextStyle默认的属性了。




感谢:
Vinay Gaba

推荐:
Google Fonts

posted @ 2021-07-09 04:02  拜雨  阅读(1386)  评论(0编辑  收藏  举报