自学Jetpack Compose 系列Compose控件Text与TextStyle的学习与使用
Posted bug樱樱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自学Jetpack Compose 系列Compose控件Text与TextStyle的学习与使用相关的知识,希望对你有一定的参考价值。
android 的TextView在Compose中是使用的Text控件
文本显示
说到文本显示,我们打开之前创建的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注解,下面我们就使用它查看预览了:
@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,// 字体粗细
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)
代码很简单,就是一个枚举类,只用两个参数:Normal和Italic
4. 设置字体粗细
设置字体粗细用的是FontWeight,我们先看一下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
internal 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的粗细效果,根据实际情况使用哪种加粗。FontWeight有一个有参构造函数,方便我们自定义粗细程度。里面内置好的也有我们比较熟悉的Bold和Normal
@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参数,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 = "红掌拨清波")
我们可以看到白毛浮绿水这句话就是不能选中的状态了
文末
我总结了一些Android核心知识点,以及一些最新的大厂面试题、知识脑图和视频资料解析。
需要的小伙伴直接点击文末小卡片免费领取哦,以后的路也希望我们能一起走下去。(谢谢大家一直以来的支持,需要的自己领取)
Android学习PDF+架构视频+面试文档+源码笔记
部分资料一览:
- 330页PDF Android学习核心笔记(内含8大板块)
- Android学习的系统对应视频
- Android进阶的系统对应学习资料
- Android BAT大厂面试题(有解析)
领取地址:
以上是关于自学Jetpack Compose 系列Compose控件Text与TextStyle的学习与使用的主要内容,如果未能解决你的问题,请参考以下文章
Jetpack Compose 深入探索系列一:Composable 函数
Jetpack Compose Runtime 与 NodeTree 管理
Android JetPack Compose组件中Scaffold的应用