• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 文本显示 (Text/Span)
2
3
4Text是文本组件,通常用于展示用户视图,如显示文章的文字内容,支持绑定自定义文本选择菜单,用户可根据需要选择不同功能,同时还可以扩展自定义菜单,丰富可用选项,进一步提升用户体验。Span则用于呈现显示行内文本。
5
6具体用法请参考[Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md)和[Span](../reference/apis-arkui/arkui-ts/ts-basic-components-span.md)组件的使用说明。
7
8
9## 创建文本
10
11Text可通过以下两种方式来创建:
12
13
14- string字符串。
15
16  ```ts
17  Text('我是一段文本')
18  ```
19
20
21![zh-cn_image_0000001563060685](figures/zh-cn_image_0000001563060685.png)
22
23
24- 引用Resource资源。
25
26  资源引用类型可以通过$r创建Resource类型对象,文件位置为/resources/base/element/string.json,具体内容如下:
27
28  ```json
29  {
30    "string": [
31      {
32        "name": "module_desc",
33        "value": "模块描述"
34      }
35    ]
36  }
37  ```
38
39  ```ts
40  Text($r('app.string.module_desc'))
41    .baselineOffset(0)
42    .fontSize(30)
43    .border({ width: 1 })
44    .padding(10)
45    .width(300)
46  ```
47
48  ![zh-cn_image_0000001511580872](figures/zh-cn_image_0000001511580872.png)
49
50
51## 添加子组件
52
53[Span](../reference/apis-arkui/arkui-ts/ts-basic-components-span.md)只能作为[Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md)和[RichEditor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md)组件的子组件显示文本内容。可以在一个Text内添加多个Span来显示一段信息,例如产品说明书、承诺书等。
54
55- 创建Span。
56
57  Span组件必须嵌入在Text组件中才能显示,单独的Span组件不会呈现任何内容。Text与Span同时配置文本内容时,Span内容覆盖Text内容。
58
59
60  ```ts
61  Text('我是Text') {
62    Span('我是Span')
63  }
64  .padding(10)
65  .borderWidth(1)
66  ```
67
68  ![zh-cn_image_0000001562700441](figures/zh-cn_image_0000001562700441.png)
69
70- 设置文本装饰线及颜色。
71
72  通过[decoration](../reference/apis-arkui/arkui-ts/ts-basic-components-span.md#decoration)设置文本装饰线及颜色。
73
74
75  ```ts
76  Text() {
77    Span('我是Span1,').fontSize(16).fontColor(Color.Grey)
78      .decoration({ type: TextDecorationType.LineThrough, color: Color.Red })
79    Span('我是Span2').fontColor(Color.Blue).fontSize(16)
80      .fontStyle(FontStyle.Italic)
81      .decoration({ type: TextDecorationType.Underline, color: Color.Black })
82    Span(',我是Span3').fontSize(16).fontColor(Color.Grey)
83      .decoration({ type: TextDecorationType.Overline, color: Color.Green })
84  }
85  .borderWidth(1)
86  .padding(10)
87  ```
88
89  ![zh-cn_image_0000001562700437](figures/zh-cn_image_0000001562700437.png)
90
91- 通过[textCase](../reference/apis-arkui/arkui-ts/ts-basic-components-span.md#textcase)设置文字一直保持大写或者小写状态。
92
93  ```ts
94  Text() {
95    Span('I am Upper-span').fontSize(12)
96      .textCase(TextCase.UpperCase)
97  }
98  .borderWidth(1)
99  .padding(10)
100  ```
101
102  ![zh-cn_image_0000001562940525](figures/zh-cn_image_0000001562940525.png)
103
104- 添加事件。
105
106  由于Span组件无尺寸信息,事件仅支持添加点击事件[onClick](../reference/apis-arkui/arkui-ts/ts-universal-events-click.md#onclick)。
107
108
109  ```ts
110  Text() {
111    Span('I am Upper-span').fontSize(12)
112      .textCase(TextCase.UpperCase)
113      .onClick(() => {
114        console.info('我是Span——onClick');
115      })
116  }
117  ```
118
119
120## 自定义文本样式
121
122- 通过[textAlign](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#textalign)属性设置文本对齐样式。
123
124  ```ts
125  Text('左对齐')
126    .width(300)
127    .textAlign(TextAlign.Start)
128    .border({ width: 1 })
129    .padding(10)
130  Text('中间对齐')
131    .width(300)
132    .textAlign(TextAlign.Center)
133    .border({ width: 1 })
134    .padding(10)
135  Text('右对齐')
136    .width(300)
137    .textAlign(TextAlign.End)
138    .border({ width: 1 })
139    .padding(10)
140  ```
141
142  ![zh-cn_image_0000001511421260](figures/zh-cn_image_0000001511421260.png)
143
144- 通过[textOverflow](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#textoverflow)属性控制文本超长处理,textOverflow需配合[maxLines](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#maxlines)一起使用(默认情况下文本自动折行)。从API version 18开始,文本超长时设置跑马灯的方式展示时,支持设置跑马灯的配置项,比如开关、步长、循环次数、方向等。
145
146  ```ts
147  Text('This is the setting of textOverflow to Clip text content This is the setting of textOverflow to None text content. This is the setting of textOverflow to Clip text content This is the setting of textOverflow to None text content.')
148    .width(250)
149    .textOverflow({ overflow: TextOverflow.None })
150    .maxLines(1)
151    .fontSize(12)
152    .border({ width: 1 })
153    .padding(10)
154  Text('我是超长文本,超出的部分显示省略号。I am an extra long text, with ellipses displayed for any excess。')
155    .width(250)
156    .textOverflow({ overflow: TextOverflow.Ellipsis })
157    .maxLines(1)
158    .fontSize(12)
159    .border({ width: 1 })
160    .padding(10)
161  Text('当文本溢出其尺寸时,文本将滚动显示。When the text overflows its dimensions, the text will scroll for displaying.')
162    .width(250)
163    .textOverflow({ overflow: TextOverflow.MARQUEE })
164    .maxLines(1)
165    .fontSize(12)
166    .border({ width: 1 })
167    .padding(10)
168  Text('当文本溢出其尺寸时,文本将滚动显示,支持设置跑马灯配置项。When the text overflows its dimensions, the text will scroll for displaying.')
169    .width(250)
170    .textOverflow({ overflow: TextOverflow.MARQUEE })
171    .maxLines(1)
172    .fontSize(12)
173    .border({ width: 1 })
174    .padding(10)
175    .marqueeOptions({
176      start: true,
177      fromStart: true,
178      step: 6,
179      loop: -1,
180      delay: 0,
181      fadeout: false,
182      marqueeStartPolicy: MarqueeStartPolicy.DEFAULT
183    })
184  ```
185
186  ![zh-cn_image_0000001563060701](figures/zh-cn_image_0000001563060701.gif)
187
188- 通过[lineHeight](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#lineheight)属性设置文本行高。
189
190  ```ts
191  Text('This is the text with the line height set. This is the text with the line height set.')
192    .width(300).fontSize(12).border({ width: 1 }).padding(10)
193  Text('This is the text with the line height set. This is the text with the line height set.')
194    .width(300).fontSize(12).border({ width: 1 }).padding(10)
195    .lineHeight(20)
196  ```
197
198  ![zh-cn_image_0000001511740480](figures/zh-cn_image_0000001511740480.png)
199
200- 通过[decoration](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#decoration)属性设置文本装饰线样式及其颜色。
201
202  ```ts
203  Text('This is the text')
204    .decoration({
205      type: TextDecorationType.LineThrough,
206      color: Color.Red
207    })
208    .borderWidth(1).padding(10).margin(5)
209  Text('This is the text')
210    .decoration({
211      type: TextDecorationType.Overline,
212      color: Color.Red
213    })
214    .borderWidth(1).padding(10).margin(5)
215  Text('This is the text')
216    .decoration({
217      type: TextDecorationType.Underline,
218      color: Color.Red
219    })
220    .borderWidth(1).padding(10).margin(5)
221  ```
222
223  ![zh-cn_image_0000001511580888](figures/zh-cn_image_0000001511580888.png)
224
225- 通过[baselineOffset](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#baselineoffset)属性设置文本基线的偏移量。
226
227  ```ts
228  Text('This is the text content with baselineOffset 0.')
229    .baselineOffset(0)
230    .fontSize(12)
231    .border({ width: 1 })
232    .padding(10)
233    .width('100%')
234    .margin(5)
235  Text('This is the text content with baselineOffset 30.')
236    .baselineOffset(30)
237    .fontSize(12)
238    .border({ width: 1 })
239    .padding(10)
240    .width('100%')
241    .margin(5)
242  Text('This is the text content with baselineOffset -20.')
243    .baselineOffset(-20)
244    .fontSize(12)
245    .border({ width: 1 })
246    .padding(10)
247    .width('100%')
248    .margin(5)
249  ```
250
251  ![zh-cn_image_0000001562820789](figures/zh-cn_image_0000001562820789.png)
252
253- 通过[letterSpacing](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#letterspacing)属性设置文本字符间距。
254
255  ```ts
256  Text('This is the text content with letterSpacing 0.')
257    .letterSpacing(0)
258    .fontSize(12)
259    .border({ width: 1 })
260    .padding(10)
261    .width('100%')
262    .margin(5)
263  Text('This is the text content with letterSpacing 3.')
264    .letterSpacing(3)
265    .fontSize(12)
266    .border({ width: 1 })
267    .padding(10)
268    .width('100%')
269    .margin(5)
270  Text('This is the text content with letterSpacing -1.')
271    .letterSpacing(-1)
272    .fontSize(12)
273    .border({ width: 1 })
274    .padding(10)
275    .width('100%')
276    .margin(5)
277  ```
278
279  ![zh-cn_image_0000001562940513](figures/zh-cn_image_0000001562940513.png)
280
281- 通过[minFontSize](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#minfontsize)与[maxFontSize](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#maxfontsize)自适应字体大小。
282
283  minFontSize用于设置文本的最小显示字号,maxFontSize用于设置文本的最大显示字号。这两个属性必须同时设置才能生效,并且需要与[maxLines](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#maxlines)属性或布局大小限制配合使用,单独设置任一属性将不会产生效果。
284
285  ```ts
286  Text('我的最大字号为30,最小字号为5,宽度为250,maxLines为1')
287    .width(250)
288    .maxLines(1)
289    .maxFontSize(30)
290    .minFontSize(5)
291    .border({ width: 1 })
292    .padding(10)
293    .margin(5)
294  Text('我的最大字号为30,最小字号为5,宽度为250,maxLines为2')
295    .width(250)
296    .maxLines(2)
297    .maxFontSize(30)
298    .minFontSize(5)
299    .border({ width: 1 })
300    .padding(10)
301    .margin(5)
302  Text('我的最大字号为30,最小字号为15,宽度为250,高度为50')
303    .width(250)
304    .height(50)
305    .maxFontSize(30)
306    .minFontSize(15)
307    .border({ width: 1 })
308    .padding(10)
309    .margin(5)
310  Text('我的最大字号为30,最小字号为15,宽度为250,高度为100')
311    .width(250)
312    .height(100)
313    .maxFontSize(30)
314    .minFontSize(15)
315    .border({ width: 1 })
316    .padding(10)
317    .margin(5)
318  ```
319
320  ![zh-cn_image_0000001511740472](figures/zh-cn_image_0000001511740472.png)
321
322- 通过[textCase](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#textcase)属性设置文本大小写。
323
324  ```ts
325  Text('This is the text content with textCase set to Normal.')
326    .textCase(TextCase.Normal)
327    .padding(10)
328    .border({ width: 1 })
329    .padding(10)
330    .margin(5)
331  // 文本全小写展示
332  Text('This is the text content with textCase set to LowerCase.')
333    .textCase(TextCase.LowerCase)
334    .border({ width: 1 })
335    .padding(10)
336    .margin(5)
337  // 文本全大写展示
338  Text('This is the text content with textCase set to UpperCase.')
339    .textCase(TextCase.UpperCase)
340    .border({ width: 1 })
341    .padding(10)
342    .margin(5)
343  ```
344
345  ![zh-cn_image_0000001562940529](figures/zh-cn_image_0000001562940529.png)
346
347- 通过[copyOption](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#copyoption9)属性设置文本是否可复制粘贴。
348
349  ```ts
350  Text("这是一段可复制文本")
351    .fontSize(30)
352    .copyOption(CopyOptions.InApp)
353  ```
354
355  ![zh-cn_image_0000001511580868](figures/zh-cn_image_0000001511580868.png)
356
357
358## 添加事件
359
360Text组件可以添加通用事件,可以绑定[onClick](../reference/apis-arkui/arkui-ts/ts-universal-events-click.md#onclick)、[onTouch](../reference/apis-arkui/arkui-ts/ts-universal-events-touch.md#ontouch)等事件来响应操作。
361
362```ts
363Text('点我')
364  .onClick(() => {
365      console.info('我是Text的点击响应事件');
366   })
367```
368
369## 选中菜单
370
371- Text被选中时会弹出包含复制、翻译、搜索的菜单。
372
373  Text组件需要设置[copyOption](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#copyoption9)属性才可以被选中。
374
375  ```ts
376  Text("这是一段文本,用来展示选中菜单")
377    .fontSize(30)
378    .copyOption(CopyOptions.InApp)
379  ```
380  ![Text_select_menu](figures/Text_select_menu.jpg)
381
382- Text组件通过设置[bindSelectionMenu](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#bindselectionmenu11)属性绑定自定义选择菜单。
383
384  ```ts
385  Text("这是一段文本,用来展示选中菜单", this.options)
386    .fontSize(30)
387    .copyOption(CopyOptions.InApp)
388    .bindSelectionMenu(TextSpanType.TEXT, this.RightClickTextCustomMenu, TextResponseType.RIGHT_CLICK, {
389      onAppear: () => {
390        console.info('自定义选择菜单弹出时触发该回调');
391      },
392      onDisappear: () => {
393        console.info('自定义选择菜单关闭时触发该回调');
394      }
395    })
396  ```
397
398  ```ts
399  // 定义菜单项
400  @Builder
401  RightClickTextCustomMenu() {
402    Column() {
403      Menu() {
404        MenuItemGroup() {
405          MenuItem({ startIcon: $r('app.media.app_icon'), content: "CustomMenu One", labelInfo: "" })
406            .onClick(() => {
407              // 使用closeSelectionMenu接口关闭菜单
408              this.controller.closeSelectionMenu();
409            })
410          MenuItem({ startIcon: $r('app.media.app_icon'), content: "CustomMenu Two", labelInfo: "" })
411          MenuItem({ startIcon: $r('app.media.app_icon'), content: "CustomMenu Three", labelInfo: "" })
412        }
413      }.backgroundColor('#F0F0F0')
414    }
415  }
416  ```
417  ![text_bindselectionmenu](figures/text_bindselectionmenu.gif)
418
419- Text组件通过设置[editMenuOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#editmenuoptions12)属性扩展自定义选择菜单,可以设置扩展项的文本内容、图标以及回调方法。
420
421  ```ts
422  Text('这是一段文本,用来展示选中菜单')
423    .fontSize(20)
424    .copyOption(CopyOptions.LocalDevice)
425    .editMenuOptions({
426      onCreateMenu: this.onCreateMenu, onMenuItemClick: this.onMenuItemClick
427    })
428  ```
429
430  ```ts
431  // 定义onCreateMenu,onMenuItemClick
432  onCreateMenu = (menuItems: Array<TextMenuItem>) => {
433    let item1: TextMenuItem = {
434      content: 'customMenu1',
435      icon: $r('app.media.app_icon'),
436      id: TextMenuItemId.of('customMenu1'),
437    };
438    let item2: TextMenuItem = {
439      content: 'customMenu2',
440      id: TextMenuItemId.of('customMenu2'),
441      icon: $r('app.media.app_icon'),
442    };
443    menuItems.push(item1);
444    menuItems.unshift(item2);
445    return menuItems;
446  }
447
448  onMenuItemClick = (menuItem: TextMenuItem, textRange: TextRange) => {
449    if (menuItem.id.equals(TextMenuItemId.of("customMenu2"))) {
450      console.log("拦截 id: customMenu2 start:" + textRange.start + "; end:" + textRange.end);
451      return true;
452    }
453    if (menuItem.id.equals(TextMenuItemId.COPY)) {
454      console.log("拦截 COPY start:" + textRange.start + "; end:" + textRange.end);
455      return true;
456    }
457    if (menuItem.id.equals(TextMenuItemId.SELECT_ALL)) {
458      console.log("不拦截 SELECT_ALL start:" + textRange.start + "; end:" + textRange.end);
459      return false;
460    }
461    return false;
462  };
463  ```
464  ![text_editmenuoptions](figures/text_editmenuoptions.gif)
465
466## 场景示例
467
468该示例通过maxLines、textOverflow、textAlign、constraintSize属性展示了热搜榜的效果。
469
470```ts
471// xxx.ets
472@Entry
473@Component
474struct TextExample {
475  build() {
476    Column() {
477      Row() {
478        Text("1").fontSize(14).fontColor(Color.Red).margin({ left: 10, right: 10 })
479        Text("我是热搜词条1")
480          .fontSize(12)
481          .fontColor(Color.Blue)
482          .maxLines(1)
483          .textOverflow({ overflow: TextOverflow.Ellipsis })
484          .fontWeight(300)
485        Text("爆")
486          .margin({ left: 6 })
487          .textAlign(TextAlign.Center)
488          .fontSize(10)
489          .fontColor(Color.White)
490          .fontWeight(600)
491          .backgroundColor(0x770100)
492          .borderRadius(5)
493          .width(15)
494          .height(14)
495      }.width('100%').margin(5)
496
497      Row() {
498        Text("2").fontSize(14).fontColor(Color.Red).margin({ left: 10, right: 10 })
499        Text("我是热搜词条2 我是热搜词条2 我是热搜词条2 我是热搜词条2 我是热搜词条2")
500          .fontSize(12)
501          .fontColor(Color.Blue)
502          .fontWeight(300)
503          .constraintSize({ maxWidth: 200 })
504          .maxLines(1)
505          .textOverflow({ overflow: TextOverflow.Ellipsis })
506        Text("热")
507          .margin({ left: 6 })
508          .textAlign(TextAlign.Center)
509          .fontSize(10)
510          .fontColor(Color.White)
511          .fontWeight(600)
512          .backgroundColor(0xCC5500)
513          .borderRadius(5)
514          .width(15)
515          .height(14)
516      }.width('100%').margin(5)
517
518      Row() {
519        Text("3").fontSize(14).fontColor(Color.Orange).margin({ left: 10, right: 10 })
520        Text("我是热搜词条3")
521          .fontSize(12)
522          .fontColor(Color.Blue)
523          .fontWeight(300)
524          .maxLines(1)
525          .constraintSize({ maxWidth: 200 })
526          .textOverflow({ overflow: TextOverflow.Ellipsis })
527        Text("热")
528          .margin({ left: 6 })
529          .textAlign(TextAlign.Center)
530          .fontSize(10)
531          .fontColor(Color.White)
532          .fontWeight(600)
533          .backgroundColor(0xCC5500)
534          .borderRadius(5)
535          .width(15)
536          .height(14)
537      }.width('100%').margin(5)
538
539      Row() {
540        Text("4").fontSize(14).fontColor(Color.Grey).margin({ left: 10, right: 10 })
541        Text("我是热搜词条4 我是热搜词条4 我是热搜词条4 我是热搜词条4 我是热搜词条4")
542          .fontSize(12)
543          .fontColor(Color.Blue)
544          .fontWeight(300)
545          .constraintSize({ maxWidth: 200 })
546          .maxLines(1)
547          .textOverflow({ overflow: TextOverflow.Ellipsis })
548      }.width('100%').margin(5)
549    }.width('100%')
550  }
551}
552
553```
554
555![zh-cn_image_0000001562820805](figures/zh-cn_image_0000001562820805.png)
556<!--RP1--><!--RP1End-->
557