暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Compose中Text的简易用法

奔波儿灞取经 2021-07-06
1911

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可在这里下载: https://gitee.com/lloydfinch/compose-text-demo

当然,Text的用法远不止此,更多的用法可以查看官方API即可。


数据库
文章转载自 奔波儿灞取经,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

玻璃钢生产厂家北京主题商场美陈采购哈密商场美陈开原玻璃钢座椅雕塑苏州玻璃钢广场雕塑厂家供应邯郸价值观玻璃钢人物雕塑公司酒店玻璃钢雕塑小品沈阳玻璃钢雕塑品牌玻璃钢雕塑外衣果蔬玻璃钢雕塑芜湖玻璃钢民俗雕塑设计深圳大型主题商场美陈制作玻璃钢雕塑制作玻璃钢蝴蝶柱雕塑彩绘玻璃钢雕塑摆件奇特的熊猫玻璃钢雕塑玻璃钢景观雕塑哪家正规绍兴动物玻璃钢雕塑生产厂家扬州玻璃钢雕塑江苏玻璃钢花盆开发太原商场中庭美陈布置安阳锻铜玻璃钢仿铜雕塑生产黑河玻璃钢十二生肖雕塑城市玻璃钢雕塑设计兴化玻璃钢南瓜屋雕塑南京玻璃钢不锈钢雕塑芜湖玻璃钢艺术雕塑设计安徽玻璃钢商城广场美陈雕塑厂家高档商场开业中庭吊饰美陈布置玻璃钢卡通雕塑名玻璃钢鹿雕塑免费咨询香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化