Android 的TextView在Compose中是使用的控件
文本显示
说到文本显示,我们打开之前创建的文本Compose看项目代码:
@Composable fun Greeting(name: String) { Text(text = "Hello $name!") }
使用是你看到的Text()显示文本。Google官方建议我们使用字符串资源,方便我们在未来进行国际适应。那么如何使用字符串资源呢?
@Composable fun TestText(){ Text(text = stringResource(id = R.string.app_name)) }
在Compose中使用stringResource您可以直接读取字符串资源。接下来,我们需要预览效果。我们之前提到过注解,下面我们就使用它查看预览了:
@Preview(showBackground = true, heightDp = 100, widthDp = 200) @Composable fun TestTextPreview() { TestText() }
看看效果:
如果我们不需要进行其他设置的话,直接像上面那样使用Text如果我们需要其他设置,如何实现一些文本效果?所以我们仍然需要查看源代码:
@Composable fun Text( text: String, modifier: Modifier = Modifier,// 修饰符 color: Color = Color.Unspecified,// 文本颜色 fontSize: TextUnit = TextUnit.Unspecified,// 字号大小 fontStyle: FontStyle? = null,// 字体样式 fontWeight: FontWeight? = null,// 字体样式 fontWeight: FontWeight? = null,// 字体粗细 fontFamily: FontFamily? = null,// 字体 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// 文本的风格配置,如高色字体等 )
我们只看到text必传,其它参数有默认值。
设置文字样式
1. 文字颜色
@Composable fun TestText() { Text( text = stringResource(id = R.string.app_name), color = Color.Blue, ) }
代码很简单, 我们只是把字体的颜色设置成蓝色, 以下是预览效果:
2.字号大小
@Composable fun TestText() { Text( text = stringResource(id = R.string.app_name), color = Color.Blue, fontSize = 25.sp ) }
大小参数fontSize的类型是TextUnit。我们设置字号大小的时候使用了Int.sp其实这是形式Compose为我们写的扩展函数。Int、Float、Double可以这样使用
@Stable val Float.sp: TextUnit get() = pack(UNIT_TYPE_SP, this) @Stable val Double.sp: TextUnit get() = pack(UNIT_TYPE_SP, this.toFloat()) @Stable val Int.sp: TextUnit get() = pack(UNIT_TYPE_SP, this.toFloat())
3. 设置斜体
@Composable fun TestText() { Text( text = stringResource(id = R.string.app_name), color = Color.Blue, fontSize = 25.sp, fontStyle = FontStyle.Italic, ) }
我们看一下FontStyle的源码:
inline class FontStyle(val value: Int) { override fun toString(): String { return when (this) { Normal -> "Normal" Italic -> "Italic" else -> "Invalid" } } companion object { /** Use the upright glyphs */ val Normal = FontStyle(0) /** Use glyphs designed for slanting */ val Italic = FontStyle(1) /** Returns a list of possible values of [FontStyle]. */ fun values(): List<FontStyle> = listOf(Normal, Italic) } }
代码很简单,就是枚举类,只有两个参数:和
4. 设置字体厚度
用于设置字体厚度,让我们先看看FontWeight的源码
@Immutable class FontWeight(val weight: Int) : Comparable<FontWeight> { companion object { @Stable val W100 = FontWeight(100) @Stable val W200 = FontWeight(200) @Stable val W300 = FontWeight(300) @Stable val W400 = FontWeight(400) @Stable val W500 = FontWeight(500) @Stable val W600 = FontWeight(600) @Stable val W700 = FontWeight(700) @Stable val W800 = FontWeight(800) @Stable val W900 = FontWeight(900) @Stable val Thin = W100 @Stable val ExtraLight = W200 @Stable val Light = W300 @Stable val Normal = W400 @Stable val Medium = W500 @Stable val SemiBold = W600 @Stable val Bold = W700 @Stable val ExtraBold = W800 @Stable val Black = W900 iternal val values: List<FontWeight> = listOf(
W100,
W200,
W300,
W400,
W500,
W600,
W700,
W800,
W900
)
}
init {
require(weight in 1..1000) {
"Font weight can be in range [1, 1000]. Current value: $weight"
}
}
}
代码内置了从W100 到 W900的粗细效果,根据实际情况使用哪种加粗。有一个有参构造函数,方便我们自定义粗细程度。里面内置好的也有我们比较熟悉的和
@Composable
fun TestText() {
Text(
text = stringResource(id = R.string.app_name),
color = Color.Blue,
fontSize = 25.sp,
fontStyle = FontStyle.Italic,
fontWeight = FontWeight.Bold
)
}
上面说了我们也可以自定义粗细的值:
@Composable
fun TestText() {
Text(
text = stringResource(id = R.string.app_name),
color = Color.Blue,
fontSize = 25.sp,
fontStyle = FontStyle.Italic,
fontWeight = FontWeight(10)
)
}
上面是我们把粗细值改成10的效果
5.设置字体
修改字体使用的是fontFamily参数,用于设置使用的字体。按照惯例,先看源码:
sealed class FontFamily(val canLoadSynchronously: Boolean) {
companion object {
// 默认字体
val Default: SystemFontFamily = DefaultFontFamily()
// 具有低对比度和平淡笔画结尾的字体
val SansSerif = GenericFontFamily("sans-serif")
// Scripts 的正式文本
val Serif = GenericFontFamily("serif")
// 字形具有相同固定宽度的字体
val Monospace = GenericFontFamily("monospace")
// 草书、手写字体
val Cursive = GenericFontFamily("cursive")
}
}
系统默认提供了5种字体,我们把这5种字体都使用一下看看效果:
@Composable
fun TestText() {
Column {
Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.Default)
Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.SansSerif)
Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.Serif)
Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.Monospace)
Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.Cursive)
}
}
除了系统给的字体,我们还可以添加自定义字体和字型,首先我们要讲字体文件放到res/font文件夹中。
放置完字体后,需要根据字体文件来定义fontFamily:
val customFamily = FontFamily(
Font(R.font.family_normal, FontWeight.Normal),
Font(R.font.family_bold, FontWeight.Bold),
)
然后,就可以将此fontFamily传递给Text来使用了:
Text(text = stringResource(id = R.string.app_name), fontFamily = customFamily, fontWeight = FontWeight.Bold)
6. 设置字符间距
设置字符间距使用的是Text的letterSpacing参数。参数类型和设置字号大小是一样的:
@Composable
fun TestText() {
Text(
text = stringResource(id = R.string.app_name),
letterSpacing = 5.sp
)
}
不是只有英文可是设置字符间距,中文也可以
7. 设置文字装饰
设置文字装饰用的是textDecoration参数,我先去看一下这个源码:
@Immutable
class TextDecoration internal constructor(val mask: Int) {
companion object {
@Stable
val None: TextDecoration = TextDecoration(0x0)
// 下划线
@Stable
val Underline: TextDecoration = TextDecoration(0x1)
// 删除线
@Stable
val LineThrough: TextDecoration = TextDecoration(0x2)
}
}
我们看看文字装饰怎么用?
@Composable
fun TestText() {
Column {
Text(
text = "小码农沐枫",
textDecoration = TextDecoration.None
)
Text(
text = "小码农沐枫",
textDecoration = TextDecoration.Underline
)
Text(
text = "小码农沐枫",
textDecoration = TextDecoration.LineThrough
)
}
}
8. 文字对齐方式
设置文字的对齐方式使用的是textAlign参数。参数对应的类型是TextAlign, 先看一下源码:
inline class TextAlign internal constructor(internal val value: Int) {
companion object {
val Left = TextAlign(1)
val Right = TextAlign(2)
val Center = TextAlign(3)
val Justify = TextAlign(4)
val Start = TextAlign(5)
val End = TextAlign(6)
}
}
我们以居中对齐为例:
Text(
text = "小码农沐枫",
textAlign = TextAlign.Center,
modifier = Modifier.width(200.dp)
)
9. 设置行高
设置行高使用的参数是lineHeight,参数类型也是TextUnit。
Text(
text = "小码农沐枫小码农沐枫小码农沐枫",
lineHeight = 35.sp
)
10. 文字溢出
处理文字溢出的情况,使用的参数为overflow,参数类型为TextOverflow。直接看源码:
inline class TextOverflow internal constructor(internal val value: Int) {
override fun toString(): String {
return when (this) {
Clip -> "Clip"
Ellipsis -> "Ellipsis"
Visible -> "Visible"
else -> "Invalid"
}
}
companion object {
val Clip = TextOverflow(1)
val Ellipsis = TextOverflow(2)
val Visible = TextOverflow(3)
}
}
Text(
text = "小码农沐枫小码农沐枫小码农沐枫",
overflow = TextOverflow.Ellipsis,
maxLines = 2
)
11. 文字中富文本显示
这种在登录或注册页面的底部同意隐私权限的位置经常用到。
如果要实现这种效果,我们就需要借助AnnotatedString类来实现。先看源码:
@Immutable
class AnnotatedString internal constructor(
val text: String,
val spanStyles: List<Range<SpanStyle>> = emptyList(),
val paragraphStyles: List<Range<ParagraphStyle>> = emptyList(),
internal val annotations: List<Range<out Any>> = emptyList()
)
- text: 用于表示文字内容
- spanStyles:用于在文本的特定部分指定SpanStyle
- paragraphStyles:用于指定文字对齐、文字方向、行高和文字缩进样式。
TextStyle用于Text可组合项,而SpanStyle和ParagraphStyle用于AnnotatedString。
SpanStyle和ParagraphStyle之间的区别在于:ParagraphStyle可应用于整个段落,而SpanStyle可以在字符级别应用。一旦用ParagraphStyle标记了一部分文字,该部分就会与其余部分隔开,就像开头和末尾有换行符一样。
下面看看具体使用:
@Composable
fun TestText() {
Text(buildAnnotatedString {
withStyle(style = SpanStyle(color = Color.Gray, fontSize = 14.sp)){
append("阅读并同意")
}
withStyle(style = SpanStyle(color = Color.Green, fontSize = 14.sp)){
append("《用户协议》")
}
withStyle(style = SpanStyle(color = Color.Gray, fontSize = 14.sp)){
append("和")
}
withStyle(style = SpanStyle(color = Color.Green, fontSize = 14.sp)){
append("《隐私协议》")
}
withStyle(style = SpanStyle(color = Color.Gray, fontSize = 14.sp)){
append("。")
}
})
}
设置文字选择
在Compose中支持Text的精细互动,文字选择现在更加灵活,并且可以跨各种可组合项布局进行选择。 在默认情况下,可组合项不可选择,也就是说默认情况下用户无法选择和复制文字。要启用文字选择,需要使用SelectionContainer可组合项封装文字元素:
@Composable
fun TestText() {
SelectionContainer(modifier = Modifier.fillMaxSize()) {
Text(text = "我是可以选择的, 我是可以选择的, 我是可以选择的", fontSize = 35.sp)
}
}
这种需要长按的,我们预览就看不到效果了,我们只能去运行看效果:
比如说在一段文字中,我们有一部分是不想让用户去选中的,这个应该怎么做呢?在这里我们就可以借用DisableSelection可组合项来封装不可选择的部分:
@Composable
fun TestText() {
SelectionContainer(modifier = Modifier.fillMaxSize()) {
Column {
Text(text = "鹅鹅鹅")
Text(text = "曲项向天歌")
DisableSelection {
Text(text = "白毛浮绿水")
}
Text(text = "红掌拨清波")
}
}
}
我们可以看到这句话就是不能选中的状态了
文末
我总结了一些,以及一些最新的大厂面试题、知识脑图和视频资料解析。
需要的哦,以后的路也希望我们能一起走下去。
部分资料一览: