前言
自从去年参加 Android 官方发起了 Jetpack Compose 的推广活动:Jetpack Compose
开发者挑战赛以后,再未系统的学习过 Jetpack Compose 的内容,一晃一年就过去了,官方版本已经更新至稳定版 本1.1.1
,Alpha 版本 1.2.0-alpha04
。
从今天开始,继续自学 Jetpack Compose,就从文本 Text 开始吧,用不用得上再说。
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 | 文本内容 |
modifer | 修饰器 |
color | 文本颜色 |
fontSize | 文本大小 |
fontStyle | 字体样式 |
fontWeight | 文本粗细 |
fontFamily | 文本字体 |
letterSpacing | 文字间隔 |
textDecoration | 文本装饰 |
textAlign | 文本对齐方式 |
lineHeight | 行高 |
overflow | 文本溢出处理方式 |
softWrap | 自动换行 |
maxLines | 最大显示行数 |
onTextLayout | 计算布局回调函数 |
style | 文本样式 |
另外还有一个 Text 函数,大同小异,多出两个属性。
@Composable
fun Text(
text: AnnotatedString,
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,
inlineContent: Map<String, InlineTextContent> = mapOf(),
onTextLayout: (TextLayoutResult) -> Unit = {},
style: TextStyle = LocalTextStyle.current
)
属性 | 含义 |
---|---|
text | AnnotatedString 类型,可显示内容更加丰富 |
inlineContent | 内联内容 |
属性示例
color
val colors = listOf(Purple200, Purple500, Purple700)
items(3) {
Text(text = "假如我是一只鸟,", color = colors[it])
}
fontSize
items(3) {
Text(text = "我也应该用嘶哑的喉咙歌唱,", fontSize = (12 * (it + 1)).sp)
}
fontStyle
items(2) {
Text(text = "这被暴风雨所打击着的土地,", fontStyle = FontStyle.values()[it])
}
fontWeight
items(9) {
Text(text = "这永远汹涌着我们的悲愤的河流,", fontWeight = FontWeight(100 * (it + 1)))
}
fontFamily
@Composable
fun FontFamilySansSerifSample() {
Text(
text = "Demo Text sans-serif",
fontFamily = FontFamily.SansSerif
)
}
@Composable
fun FontFamilySerifSample() {
Text(
text = "Demo Text serif",
fontFamily = FontFamily.Serif
)
}
@Composable
fun FontFamilyMonospaceSample() {
Text(
text = "Demo Text monospace",
fontFamily = FontFamily.Monospace
)
}
@Composable
fun FontFamilyCursiveSample() {
Text(
text = "Demo Text cursive",
fontFamily = FontFamily.Cursive
)
}
@Composable
fun CustomFontFamilySample() {
val fontFamily = FontFamily(
Font(
resId = R.font.myfont_regular,
weight = FontWeight.W400,
style = FontStyle.Normal
),
Font(
resId = R.font.myfont_italic,
weight = FontWeight.W400,
style = FontStyle.Italic
)
)
Text(text = "Demo Text", fontFamily = fontFamily)
}
@Composable
fun FontFamilySynthesisSample() {
// The font family contains a single font, with normal weight
val fontFamily = FontFamily(
Font(resId = R.font.myfont_regular, weight = FontWeight.Normal)
)
// Configuring the Text composable to be bold
// Using FontSynthesis.Weight to have the system render the font bold my making the glyphs
// thicker
Text(
text = "Demo Text",
style = TextStyle(
fontFamily = fontFamily,
fontWeight = FontWeight.Bold,
fontSynthesis = FontSynthesis.Weight
)
)
}
letterSpacing
items(5) {
Text(text = "和那来自林间的无比温柔的黎明,", letterSpacing = (it * 5).sp)
}
textDecoration
@Composable
fun TextDecorationLineThroughSample() {
Text(
text = "Demo Text",
textDecoration = TextDecoration.LineThrough
)
}
@Composable
fun TextDecorationUnderlineSample() {
Text(
text = "Demo Text",
textDecoration = TextDecoration.Underline
)
}
@Composable
fun TextDecorationCombinedSample() {
Text(
text = "Demo Text",
textDecoration = TextDecoration.Underline + TextDecoration.LineThrough
)
}
textAlign
val textAligns = listOf(
TextAlign.Left,
TextAlign.Right,
TextAlign.Center,
TextAlign.Justify,
TextAlign.Start,
TextAlign.End
)
items(6) {
Text(
modifier = Modifier.fillMaxWidth(),
text = "——连羽毛也腐烂在土地里面,",
textAlign = textAligns[it]
)
}
lineHeight
items(4) {
Text(
modifier = Modifier.fillMaxWidth(),
text = "上帝, 请赐予我平静, 去接受我无法改变的. 给予我勇气, 去改变我能改变的, 赐我智慧, 分辨这两者的区别.",
lineHeight = (20 * (it + 1)).sp
)
}
overflow
@Composable
fun TextOverflowClipSample() {
Text(
text = "Hello ".repeat(2),
modifier = Modifier.size(100.dp, 70.dp).background(Color.Cyan),
fontSize = 35.sp,
overflow = TextOverflow.Clip
)
}
@Composable
fun TextOverflowEllipsisSample() {
Text(
text = "Hello ".repeat(2),
modifier = Modifier.width(100.dp).background(Color.Cyan),
fontSize = 35.sp,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
}
@Composable
fun TextOverflowVisibleFixedSizeSample() {
val background = remember { mutableStateOf(Color.Cyan) }
Box(modifier = Modifier.size(100.dp, 100.dp)) {
Text(
text = "Hello ".repeat(2),
modifier = Modifier.size(100.dp, 70.dp)
.background(background.value)
.clickable {
background.value = if (background.value == Color.Cyan) {
Color.Gray
} else {
Color.Cyan
}
},
fontSize = 35.sp,
overflow = TextOverflow.Visible
)
}
}
@Composable
fun TextOverflowVisibleMinHeightSample() {
val background = remember { mutableStateOf(Color.Cyan) }
val count = remember { mutableStateOf(1) }
Box(modifier = Modifier.size(100.dp, 100.dp)) {
Text(
text = "Hello".repeat(count.value),
modifier = Modifier.width(100.dp).heightIn(min = 70.dp)
.background(background.value)
.clickable {
background.value =
if (background.value == Color.Cyan) Color.Gray else Color.Cyan
count.value = if (count.value == 1) 2 else 1
},
fontSize = 35.sp,
overflow = TextOverflow.Visible
)
}
}
softWrap
items(2) {
Text(
modifier = Modifier.fillMaxWidth(),
text = "上帝, 请赐予我平静, 去接受我无法改变的. 给予我勇气, 去改变我能改变的, 赐我智慧, 分辨这两者的区别.",
softWrap = it == 1
)
}
maxLines
item {
Text(
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " +
"incididunt ut labore et dolore magna aliqua.\nUt enim ad minim veniam, quis " +
"nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
maxLines = 2
)
}
onTextLayout
item {
Text(
modifier = Modifier.fillMaxWidth(),
text = "上帝, 请赐予我平静, 去接受我无法改变的. 给予我勇气, 去改变我能改变的, 赐我智慧, 分辨这两者的区别.",
onTextLayout = {
appLog("onTextLayout => size: ${it.size}")
}
)
}
textStyle
@Composable
fun TextStyleSample() {
Text(
text = "Demo Text",
style = TextStyle(
color = Color.Red,
fontSize = 16.sp,
fontFamily = FontFamily.Monospace,
fontWeight = FontWeight.W800,
fontStyle = FontStyle.Italic,
letterSpacing = 0.5.em,
background = Color.LightGray,
textDecoration = TextDecoration.Underline
)
)
}
annotatedString
Text(text = with(AnnotatedString.Builder("Hello")) {
// push green text style so that any appended text will be green
pushStyle(SpanStyle(color = Color.Green))
// append new text, this text will be rendered as green
append(" World")
// pop the green style
pop()
// append a string without style
append("!")
// then style the last added word as red, exclamation mark will be red
addStyle(SpanStyle(color = Color.Red), "Hello World".length, this.length)
toAnnotatedString()
})
inlineTextContent
@Composable
fun InlineTextContentSample() {
val myId = "inlineContent"
val text = buildAnnotatedString {
append("Hello")
// Append a placeholder string "[myBox]" and attach an annotation "inlineContent" on it.
appendInlineContent(myId, "[myBox]")
}
val inlineContent = mapOf(
Pair(
// This tells the [BasicText] to replace the placeholder string "[myBox]" by
// the composable given in the [InlineTextContent] object.
myId,
InlineTextContent(
// Placeholder tells text layout the expected size and vertical alignment of
// children composable.
Placeholder(
width = 0.5.em,
height = 0.5.em,
placeholderVerticalAlign = PlaceholderVerticalAlign.AboveBaseline
)
) {
// This [Box] will fill maximum size, which is specified by the [Placeholder]
// above. Notice the width and height in [Placeholder] are specified in TextUnit,
// and are converted into pixel by text layout.
Box(modifier = Modifier.fillMaxSize().background(color = Color.Red))
}
)
)
Text(text = text, inlineContent = inlineContent)
}
onTextLayout
Text(
modifier = Modifier.fillMaxWidth(),
text = "上帝, 请赐予我平静, 去接受我无法改变的. 给予我勇气, 去改变我能改变的, 赐我智慧, 分辨这两者的区别.",
onTextLayout = {
appLog("onTextLayout => size: ${it.size}")
}
)
可选择文本
SelectionContainer(modifier = Modifier.fillMaxWidth()) {
Text(text = "You can select me, baby")
}
可点击文本
方式一:Modifier.clickable
Text(text = "使用 clickable 实现点击",
modifier = Modifier.clickable {
appLog("使用 Text clickable 属性完成点击")
})
方式二:ClickableText
ClickableText(
text = AnnotatedString(
text = "Hello World",
// make "Hello" italic.
spanStyles = listOf(
AnnotatedString.Range(SpanStyle(fontStyle = FontStyle.Italic), 0, 5)
),
// create two paragraphs with different alignment and indent settings.
paragraphStyles = listOf(
AnnotatedString.Range(ParagraphStyle(textAlign = TextAlign.Center), 0, 6),
AnnotatedString.Range(ParagraphStyle(textIndent = TextIndent(5.sp)), 6, 11)
)
), onClick = {
appLog("ClickableText 完成点击, 位置 $it")
}
)
源码
https://github.com/onlyloveyd/LearningCompose