# 4.12:图文混排
ArkUI 开发框架提供了 Span
和 ImageSpan
两个基础组件来实现图文混排的场景,本节笔者简单讲述一下它们的用法。
# 4.12.1:Span组件
Span
组件用来显示一段文本,它只能作为 Text
组件的子组件使用,目前只支持文本的通用属性 (opens new window),比如设置文本的颜色、大小、样式、粗细、字体、行高和装饰线等。
# 4.12.1.1:Span定义介绍
interface SpanInterface {
(value: string | Resource): SpanAttribute;
}
2
3
Span
的构造方法接收一个 string 或者 Resource 类型的参数用来显示一个段文本,简单样例如下所示:
@Component @Entry struct SpanTest {
build() {
Column({space: 10}) {
Text("Hello, OpenHarmony") // 使用Text来显示文本
Text() {
Span("Hello, OpenHarmony") // 使用Span来显示文本
}
}
.padding(10)
.width("100%")
.height("100%")
}
}
2
3
4
5
6
7
8
9
10
11
12
13
样例运行结果如下图所示:
# 4.12.1.2:Span属性介绍
declare class SpanAttribute extends CommonMethod<SpanAttribute> {
fontColor(value: ResourceColor): SpanAttribute;
fontSize(value: number | string | Resource): SpanAttribute;
fontStyle(value: FontStyle): SpanAttribute;
fontWeight(value: number | FontWeight | string): SpanAttribute;
fontFamily(value: string | Resource): SpanAttribute;
decoration(value: {
type: TextDecorationType;
color?: ResourceColor;
}): SpanAttribute;
letterSpacing(value: number | string): SpanAttribute;
textCase(value: TextCase): SpanAttribute;
}
2
3
4
5
6
7
8
9
10
11
12
13
Span
支持的属性是 Text
组件支持属性的子集,它的显示效果和 Text
是一样的,笔者不在逐一介绍了,简单样例如下所示:
@Component @Entry struct SpanTest {
build() {
Column({space: 10}) {
Text("Hello, OpenHarmony") // 使用Text做参照物
Text() {
Span("Hello,") // 设置字体颜色、大小
.fontColor(Color.Orange)
.fontSize(20)
Span("OpenHarmony") // 设置字体颜色、大小
.fontColor(Color.Orange)
.fontSize(30)
Span("Hello") // 设置字体颜色、大小、样式、字符间距、样式、粗细
.fontColor(Color.Red)
.fontSize(20)
.fontWeight(FontWeight.Bolder)
.fontStyle(FontStyle.Italic)
.letterSpacing(3)
Span("《ArkUI实战》") // 设置字体大小、装饰线以及字母大写显示
.decoration({
type: TextDecorationType.Underline,
color: Color.Red
})
.fontSize(20)
.textCase(TextCase.UpperCase)
}
}
.padding(10)
.width("100%")
.height("100%")
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
样例运行结果如下图所示:
📢:由上述示例可知:Text
组件可以包含多个 Span
组件按照行排列的形式进行展示,超过一行默认进行换行显示。
# 4.12.1.3:Span属性继承
Span
组件允许从父组件 Text
继承属性,当 Span
未设置属性而父组件 Text
设置了相关属性时,则 Span
默认继承 Text
组件设置的属性,目前支持继承的属性包括:fontColor、fontSize、fontStyle、fontWeight、decoration、letterSpacing、textCase、fontfamily。
简单样例如下所示:
@Component @Entry struct SpanTest {
build() {
Column({space: 10}) {
Text() {
Span("Hello, OpenHarmony") // 默认参照物
}
Text() {
Span("Hello, OpenHarmony") // 继承 Text 属性
}
.fontColor(Color.Red)
.fontSize(20)
Text() {
Span("Hello, OpenHarmony") // 继承 Text 属性
Span("Hello, OpenHarmony") // 覆盖 Text 属性
.fontColor(Color.Red)
.fontSize(24)
}
.fontColor(Color.Blue)
.fontSize(20)
}
.padding(10)
.width("100%")
.height("100%")
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
样例运行结果如下图所示:
📢:由运行效果可知,当 Span
未设置相关属性而父组件 Text
设置了相关属性时,则 Span
继承父组件的熟悉,若 Span
设置了相关属性则以自身属性为准。
# 4.12.1.4:Span事件介绍
Span
目前只支持点击事件:
export declare class CommonMethod<T> {
onClick(event: (event?: ClickEvent) => void): T;
}
2
3
简单样例如下所示:
import Prompt from '@system.prompt'
@Component @Entry struct SpanTest {
build() {
Column({space: 10}) {
Text("Hello, OpenHarmony")
Text() {
Span("Hello,")
.fontColor(Color.Orange)
.fontSize(20)
.onClick((event) => {
Prompt.showToast({
message: "Hello"
})
})
Span("OpenHarmony")
.fontColor(Color.Orange)
.fontSize(30)
.onClick((event) => {
Prompt.showToast({
message: "OpenHarmony"
})
})
Span("Hello")
.fontColor(Color.Red)
.fontSize(20)
.fontWeight(FontWeight.Bolder)
.fontStyle(FontStyle.Italic)
.letterSpacing(3)
.onClick((event) => {
Prompt.showToast({
message: "Hello"
})
})
Span("《ArkUI实战》")
.decoration({
type: TextDecorationType.Underline,
color: Color.Red
})
.fontSize(20)
.textCase(TextCase.UpperCase)
.onClick((event) => {
Prompt.showToast({
message: "《ArkUI实战》"
})
})
}
}
.padding(10)
.width("100%")
.height("100%")
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 4.12.2:ImageSpan
ImageSpan
组件用来在 Text
文本组件中显示一张图片,它只能作为 Text
组件的子组件使用,目前支持文本的通用属性只有尺寸、背景以及边框。
# 4.12.2.1:ImageSpan定义介绍
interface ImageSpanInterface {
(value: ResourceStr | PixelMap): ImageSpanAttribute;
}
2
3
ImageSpan
的构造方法接收一个 ResourceStr 或者 PixelMap 类型的参数用来显示一张图片。简单样例如下所示:
@Component @Entry struct test {
build() {
Column({space: 10}) {
Text() {
ImageSpan($r("app.media.test"))
.width("100%")
.height(120)
ImageSpan("https://face.t.sinajs.cn/t4/appstyle/expression/ext/normal/8a/2018new_xin_org.png")
.width(30)
.height(30)
ImageSpan("https://face.t.sinajs.cn/t4/appstyle/expression/ext/normal/8a/2018new_xin_org.png")
.width(30)
.height(30)
ImageSpan("https://face.t.sinajs.cn/t4/appstyle/expression/ext/normal/8a/2018new_xin_org.png")
.width(30)
.height(30)
}
.fontSize(20)
.fontColor(Color.Black)
}
.padding(10)
.width("100%")
.height("100%")
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
样例运行结果如下图所示:
📢:当 ResourceStr 是一个网络地址时,需要在配置文件
module.json5
中添加网络权限:{ "module": { "name": "entry", "requestPermissions": [ { "name": "ohos.permission.INTERNET" // 配置网络权限 } ], } }
1
2
3
4
5
6
7
8
9
10
# 4.12.2.2:ImageSpan属性介绍
declare class ImageSpanAttribute extends CommonMethod<ImageSpanAttribute> {
verticalAlign(value: ImageSpanAlignment): ImageSpanAttribute;
objectFit(value: ImageFit): ImageSpanAttribute;
}
2
3
4
- objectFit: 设置图片的缩放类型,和
Image
属性一致,笔者不再多做介绍了。 - verticalAlign: 在
Text
内部既有Span
又有ImageSpan
的场景下,ImageSpan
在竖直方向上的对其方式,目前支持以下几种:- TOP: 图片上边沿与文本上边沿对齐。
- CENTER: 图片中间与文本中间对齐。
- BOTTOM(默认值): 图片下边沿与文本下边沿对齐。
- BASELINE: 图片下边沿与文本
BaseLine
对齐。
简单样例如下所示:
@Component @Entry struct test {
build() {
Column({space: 10}) {
Text() {
ImageSpan($r("app.media.test"))
.width(50)
.height(50)
Span("Hello, OpenHarmony")
}
Text() {
ImageSpan($r("app.media.test"))
.width(50)
.height(50)
.verticalAlign(ImageSpanAlignment.TOP)
Span("Hello, OpenHarmony")
}
Text() {
ImageSpan($r("app.media.test"))
.width(50)
.height(50)
.verticalAlign(ImageSpanAlignment.CENTER)
Span("Hello, OpenHarmony")
}
Text() {
ImageSpan($r("app.media.test"))
.width(50)
.height(50)
.verticalAlign(ImageSpanAlignment.BOTTOM)
Span("Hello, OpenHarmony")
}
Text() {
ImageSpan($r("app.media.test"))
.width(50)
.height(50)
.verticalAlign(ImageSpanAlignment.BASELINE)
Span("Hello, OpenHarmony")
}
}
.padding(10)
.width("100%")
.height("100%")
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
样例运行结果如下图所示:
# 4.12.2.3:ImageSpan事件介绍
ImageSpan
目前也是只支持点击事件,它和 Span
的用法一致,笔者就不在单独介绍它的用法了。
# 4.12.3:图文混排
图文混排的场景也是很常见的,比如浏览新闻类 APP 的时候经常会有图文混排的场景,在 OpenHarmony 上实现图文混排最简单的方式就是利用 Text
包含 Span
和 ImageSpan
实现,简单样例如下所示:
import Prompt from '@system.prompt'
@Component @Entry struct test {
build() {
Column({space: 10}) {
Text() {
ImageSpan($r("app.media.app_icon"))
.size({width: 25, height: 25})
.verticalAlign(ImageSpanAlignment.CENTER)
.onClick((event) => {
Prompt.showToast({
message: "Hello,《ArkUI实战》"
})
})
Span(" 新的一年已经开启,带上一本 #夜读日历# ")
.onClick((event) => {
Prompt.showToast({
message: "新的一年已经开启,带上一本 #夜读日历# ,继续乘风破浪、跨越山海吧!"
})
})
ImageSpan($r("app.media.love"))
.size({width: 25, height: 25})
.verticalAlign(ImageSpanAlignment.CENTER)
.onClick((event) => {
Prompt.showToast({
message: "感谢关注"
})
})
Span(" 继续乘风破浪、跨越山海吧!")
.onClick((event) => {
Prompt.showToast({
message: "新的一年已经开启,带上一本 #夜读日历# ,继续乘风破浪、跨越山海吧!"
})
})
ImageSpan("https://face.t.sinajs.cn/t4/appstyle/expression/ext/normal/8a/2018new_xin_org.png")
.size({width: 25, height: 25})
.verticalAlign(ImageSpanAlignment.CENTER)
.onClick((event) => {
Prompt.showToast({
message: "感谢关注"
})
})
}
.fontSize(20)
.fontColor(Color.Black)
}
.padding(10)
.width("100%")
.height("100%")
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
样例运行结果如下图所示:
# 4.12.4:小结
本节笔者简单介绍了使用 Span
和 ImageSpan
实现图文混排功能,目前笔者认为美中不足的是 Text
内部不支持使用 ForEach
循环创建多个 Span
的场景……