• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# RichEditor
2
3支持图文混排和文本交互式编辑的组件。
4
5>  **说明:**
6>
7>  该组件从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8
9
10## 子组件
11
12不包含子组件。
13
14
15## 接口
16
17RichEditor(value: RichEditorOptions)
18
19**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
20
21**系统能力:** SystemCapability.ArkUI.ArkUI.Full
22
23**参数:**
24
25| 参数名   | 类型                                    | 必填   | 说明        |
26| ----- | --------------------------------------- | ---- | ----------- |
27| value | [RichEditorOptions](#richeditoroptions) | 是    | 富文本组件初始化选项。 |
28
29RichEditor(options: RichEditorStyledStringOptions)<sup>12+</sup>
30
31
32**参数:**
33
34| 参数名   | 类型                                    | 必填   | 说明        |
35| ----- | --------------------------------------- | ---- | ----------- |
36| options | [RichEditorStyledStringOptions](#richeditorstyledstringoptions12) | 是    | 富文本组件初始化选项。 |
37
38## 属性
39
40除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性:
41
42>  **说明:**
43>
44>  align属性只支持上方、中间和下方位置的对齐方式。
45>
46>  不支持borderImage属性。
47
48### customKeyboard
49
50customKeyboard(value: CustomBuilder, options?: KeyboardOptions)
51
52设置自定义键盘。
53
54当设置自定义键盘时,输入框激活后不会打开系统输入法,而是加载指定的自定义组件。
55
56自定义键盘的高度可以通过自定义组件根节点的height属性设置,宽度不可设置,使用系统默认值。
57
58自定义键盘无法获取焦点,但是会拦截手势事件。
59
60默认在输入控件失去焦点时,关闭自定义键盘。
61
62如果设备支持拍摄输入,设置自定义键盘后,该输入框会不支持拍摄输入。
63
64**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
65
66**系统能力:** SystemCapability.ArkUI.ArkUI.Full
67
68**参数:**
69
70| 参数名                | 类型                                        | 必填 | 说明                             |
71| --------------------- | ------------------------------------------- | ---- | -------------------------------- |
72| value                 | [CustomBuilder](ts-types.md#custombuilder8) | 是   | 自定义键盘。                     <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
73| options<sup>12+</sup> | [KeyboardOptions](#keyboardoptions12)       | 否   | 设置自定义键盘是否支持避让功能。 |
74
75### bindSelectionMenu
76
77bindSelectionMenu(spanType: RichEditorSpanType, content: CustomBuilder, responseType: ResponseType | RichEditorResponseType,
78    options?: SelectionMenuOptions)
79
80设置自定义选择菜单。自定义菜单超长时,建议内部嵌套[Scroll](./ts-container-scroll.md)组件使用,避免键盘被遮挡。
81
82**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
83
84**系统能力:** SystemCapability.ArkUI.ArkUI.Full
85
86**参数:**
87
88| 参数名       | 类型                                                         | 必填 | 说明                                                      |
89| ------------ | ------------------------------------------------------------ | ---- | --------------------------------------------------------- |
90| spanType     | [RichEditorSpanType](#richeditorspantype)                    | 是   | 菜单的类型。<br/> 默认值:<br/>RichEditorSpanType.TEXT    |
91| content      | [CustomBuilder](ts-types.md#custombuilder8)                  | 是   | 菜单的内容。                                              |
92| responseType | &nbsp;[ResponseType](ts-appendix-enums.md#responsetype8)&nbsp;\|&nbsp;[RichEditorResponseType](#richeditorresponsetype11) | 是   | 菜单的响应类型。<br/> 默认值:<br/>ResponseType.LongPress |
93| options      | [SelectionMenuOptions](#selectionmenuoptions10)              | 否   | 菜单的选项。                                              |
94
95### copyOptions
96
97copyOptions(value: CopyOptions)
98
99设置组件是否支持文本内容可复制粘贴。
100
101copyOptions不为CopyOptions.None时,长按组件内容,会弹出文本选择弹框。如果通过bindSelectionMenu等方式自定义文本选择菜单,则会弹出自定义的菜单。
102
103设置copyOptions为CopyOptions.None,复制、剪切功能不生效。
104
105**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
106
107**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
108
109**系统能力:** SystemCapability.ArkUI.ArkUI.Full
110
111**参数:**
112
113| 参数名 | 类型                                             | 必填 | 说明                                                         |
114| ------ | ------------------------------------------------ | ---- | ------------------------------------------------------------ |
115| value  | [CopyOptions](ts-appendix-enums.md#copyoptions9) | 是   | 组件支持文本内容是否可复制粘贴。<br />默认值:CopyOptions.LocalDevice <br />**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。||
116
117### enableDataDetector<sup>11+</sup>
118
119enableDataDetector(enable: boolean)
120
121设置是否进行文本特殊实体识别。
122
123该接口依赖设备底层应具有文本识别能力,否则设置不会生效。
124
125当enableDataDetector设置为true,同时不设置dataDetectorConfig属性时,默认识别所有类型的实体,所识别实体的color和decoration会被更改为如下样式:
126
127```ts
128color: '#ff007dff'
129decoration:{
130  type: TextDecorationType.Underline,
131  color: '#ff007dff',
132  style: TextDecorationStyle.SOLID
133}
134```
135
136触摸点击和鼠标右键点击实体,会根据实体类型弹出对应的实体操作菜单,鼠标左键点击实体会直接响应菜单的第一个选项。
137
138对addBuilderSpan的节点文本,该功能不会生效。
139
140当copyOption设置为CopyOptions.None时,点击实体弹出的菜单没有选择文本和复制功能。
141
142**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
143
144**系统能力:** SystemCapability.ArkUI.ArkUI.Full
145
146**参数:**
147
148| 参数名 | 类型    | 必填 | 说明                              |
149| ------ | ------- | ---- | --------------------------------- |
150| enable  | boolean | 是   | 使能文本识别。<br/>默认值: false |
151
152### dataDetectorConfig<sup>11+</sup>
153
154dataDetectorConfig(config: TextDataDetectorConfig)
155
156设置文本识别配置。
157
158需配合[enableDataDetector](#enabledatadetector11)一起使用,设置enableDataDetector为true时,dataDetectorConfig的配置才能生效。
159
160当有两个实体A、B重叠时,按以下规则保留实体:
161
1621.&nbsp;若A&nbsp;⊂&nbsp;B,则保留B,反之则保留A。
163
1642.&nbsp;当A&nbsp;⊄&nbsp;B且B&nbsp;⊄&nbsp;A时,若A.start&nbsp;<&nbsp;B.start,则保留A,反之则保留B。
165
166**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
167
168**系统能力:** SystemCapability.ArkUI.ArkUI.Full
169
170**参数:**
171
172| 参数名 | 类型                                                        | 必填 | 说明                                                         |
173| ------ | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ |
174| config | [TextDataDetectorConfig](ts-text-common.md#textdatadetectorconfig11对象说明) | 是   | 文本识别配置。|
175
176### enablePreviewText<sup>12+</sup>
177
178enablePreviewText(enable: boolean)
179
180设置是否开启预上屏功能。
181
182**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
183
184**系统能力:** SystemCapability.ArkUI.ArkUI.Full
185
186**参数:**
187
188| 参数名 | 类型    | 必填 | 说明                              |
189| ------ | ------- | ---- | --------------------------------- |
190| enable  | boolean | 是   | 使能预上屏功能。<br/>默认值: true |
191
192>  **说明:**
193>
194>  该接口在CAPI场景使用时下,默认关闭。可以在工程的module.json5中配置[metadata](../../../../application-dev/quick-start/module-structure.md#metadata对象内部结构)字段控制是否启用预上屏,配置如下:
195> ```json
196> "metadata": [
197>  {
198>     "name": "can_preview_text",
199>     "value": "true",
200>  }
201> ]
202> ```
203
204### placeholder<sup>12+</sup>
205
206placeholder(value: ResourceStr, style?: PlaceholderStyle)
207
208设置无输入时的提示文本。
209
210**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
211
212**系统能力:** SystemCapability.ArkUI.ArkUI.Full
213
214**参数:**
215
216| 参数名 | 类型                                    | 必填 | 说明                                                    |
217| ------ | --------------------------------------- | ---- | ------------------------------------------------------- |
218| value  | [ResourceStr](ts-types.md#resourcestr)  | 是   | 无输入时的提示文本。                                    |
219| style  | [PlaceholderStyle](#placeholderstyle12) | 否   | 添加提示文本的字体样式。<br />style缺省时默认跟随主题。 |
220
221### caretColor<sup>12+</sup>
222
223caretColor(value: ResourceColor)
224
225设置输入框光标、手柄颜色。
226
227**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
228
229**系统能力:** SystemCapability.ArkUI.ArkUI.Full
230
231**参数:**
232
233| 参数名 | 类型                                       | 必填 | 说明                                   |
234| ------ | ------------------------------------------ | ---- | -------------------------------------- |
235| value  | [ResourceColor](ts-types.md#resourcecolor) | 是   | 输入框光标、手柄颜色。<br/>默认值:'#007DFF' |
236
237### selectedBackgroundColor<sup>12+</sup>
238
239selectedBackgroundColor(value: ResourceColor)
240
241设置文本选中底板颜色。如果未设置不透明度,默认为20%不透明度。
242
243**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
244
245**系统能力:** SystemCapability.ArkUI.ArkUI.Full
246
247**参数:**
248
249| 参数名 | 类型                                       | 必填 | 说明                                       |
250| ------ | ------------------------------------------ | ---- | ------------------------------------------ |
251| value  | [ResourceColor](ts-types.md#resourcecolor) | 是   | 文本选中底板颜色。<br/>默认为20%不透明度。 |
252
253### editMenuOptions<sup>12+</sup>
254
255editMenuOptions(editMenu: EditMenuOptions)
256
257设置自定义菜单扩展项,允许用户设置扩展项的文本内容、图标、回调方法。
258
259**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
260
261
262**元服务API:** 从API version 12开始,该接口支持在元服务中使用。
263
264**系统能力:** SystemCapability.ArkUI.ArkUI.Full
265
266**参数:**
267
268| 参数名 | 类型                                          | 必填 | 说明                                          |
269| ------ | --------------------------------------------- | ---- | --------------------------------------------- |
270| editMenu  | [EditMenuOptions](ts-text-common.md#editmenuoptions对象说明) | 是   | 扩展菜单选项。 |
271
272### enterKeyType<sup>12+</sup>
273
274enterKeyType(value: EnterKeyType)
275
276设置软键盘输入法回车键类型。
277
278**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
279
280**系统能力:** SystemCapability.ArkUI.ArkUI.Full
281
282**参数:**
283
284| 参数名 | 类型   | 必填 | 说明                                |
285| ------ | ------ | ---- | ----------------------------------- |
286| value  | [EnterKeyType](ts-types.md#enterkeytype枚举说明) | 是   | 键盘输入法回车键类型。<br/>默认为EnterKeyType.NEW_LINE。 |
287
288### enableKeyboardOnFocus<sup>12+</sup>
289
290enableKeyboardOnFocus(isEnabled: boolean)
291
292设置RichEditor通过点击以外的方式获焦时,是否主动拉起软键盘。
293
294
295**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
296
297**系统能力:** SystemCapability.ArkUI.ArkUI.Full
298
299**参数:**
300
301| 参数名 | 类型 | 必填 | 说明 |
302| ------ | ------- | ---- | ----------------------------------------------------------- |
303| isEnabled  | boolean | 是   | 通过点击以外的方式获焦时,是否主动拉起软键盘。<br/>默认值:true |
304
305### barState<sup>13+</sup>
306
307barState(state: BarState)
308
309设置RichEditor编辑态时滚动条的显示模式。
310
311**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。
312
313**系统能力:** SystemCapability.ArkUI.ArkUI.Full
314
315**参数:**
316
317| 参数名 | 类型 | 必填 | 说明 |
318| ------ | ----------------------------------------- | ---- | ------------------------------------------------------ |
319| state | [BarState](ts-appendix-enums.md#barstate) | 是   | 输入框编辑态时滚动条的显示模式。<br/>默认值:BarState.Auto |
320
321### enableHapticFeedback<sup>13+</sup>
322
323enableHapticFeedback(isEnabled: boolean)
324
325设置RichEditor是否支持触控反馈。
326
327**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。
328
329**系统能力:** SystemCapability.ArkUI.ArkUI.Full
330
331| 参数名 | 类型                                          | 必填  | 说明                                                                                  |
332| ------ | --------------------------------------------- |-----|-------------------------------------------------------------------------------------|
333| isEnabled  | boolean | 是   | 是否支持触控反馈。<br/>默认值:true,true表示开启触控反馈,false表示不开启触控反馈。<br/>设置为true后是否生效,还取决于系统的硬件是否支持。 |
334
335## 事件
336
337除支持[通用事件](ts-universal-events-click.md)外,还支持[OnDidChangeCallback](ts-text-common.md#ondidchangecallback12)、[StyledStringChangedListener](ts-text-common.md#styledstringchangedlistener12)、[StyledStringChangeValue](ts-text-common.md#styledstringchangevalue12)和以下事件:
338
339### onReady
340
341onReady(callback:Callback\<void\>)
342
343富文本组件初始化完成后,触发回调。
344
345**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
346
347**系统能力:** SystemCapability.ArkUI.ArkUI.Full
348
349**参数:**
350
351| 参数名   | 类型                                    | 必填   | 说明        |
352| ----- | --------------------------------------- | ---- | ----------- |
353| callback |Callback\<void\> | 是    | 订阅富文本组件初始化完成的回调。 |
354
355### onSelect
356
357onSelect(callback:Callback\<[RichEditorSelection](#richeditorselection)\>)
358
359鼠标左键双击选中内容时,会触发回调;松开鼠标左键后,会再次触发回调。
360
361手指长按选中内容时,会触发回调;松开手指后,会再次触发回调。
362
363使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。
364
365**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
366
367**系统能力:** SystemCapability.ArkUI.ArkUI.Full
368
369**参数:**
370
371| 参数名 | 类型                                        | 必填 | 说明                 |
372| ------ | ------------------------------------------- | ---- | -------------------- |
373| callback | Callback\<[RichEditorSelection](#richeditorselection)\> | 是   | [RichEditorSelection](#richeditorselection)为选中的所有span信息。<br/>选择时触发的回调。 |
374
375### aboutToIMEInput
376
377aboutToIMEInput(callback:Callback\<[RichEditorInsertValue](#richeditorinsertvalue), boolean\>)
378
379输入法输入内容前,触发回调。
380
381使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。
382
383**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
384
385**系统能力:** SystemCapability.ArkUI.ArkUI.Full
386
387**参数:**
388
389| 参数名 | 类型                                        | 必填 | 说明                 |
390| ------ | ------------------------------------------- | ---- | -------------------- |
391| callback | Callback\<[RichEditorInsertValue](#richeditorinsertvalue), boolean\> | 是   | [RichEditorInsertValue](#richeditorinsertvalue)为输入法将要输入内容信息。<br/>true:组件执行添加内容操作。<br/>false:组件不执行添加内容操作<br/>输入法输入内容前的回调。|
392
393### onDidIMEInput<sup>12+</sup>
394
395onDidIMEInput(callback:Callback\<TextRange>)
396
397输入法完成输入时,触发回调。
398
399使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。
400
401**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
402
403**系统能力:** SystemCapability.ArkUI.ArkUI.Full
404
405**参数:**
406
407| 参数名 | 类型                                        | 必填 | 说明                 |
408| ------ | ------------------------------------------- | ---- | -------------------- |
409| callback | Callback\<[TextRange](ts-text-common.md#textrange12)\> | 是 | TextRange为输入法本次输入内容的范围。<br/>输入法完成输入时的回调。|
410
411### onIMEInputComplete
412
413onIMEInputComplete(callback:Callback\<[RichEditorTextSpanResult](#richeditortextspanresult)\>)
414
415输入法完成输入后,触发回调。
416
417使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。
418
419**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
420
421**系统能力:** SystemCapability.ArkUI.ArkUI.Full
422
423**参数:**
424
425| 参数名 | 类型                                        | 必填 | 说明                 |
426| ------ | ------------------------------------------- | ---- | -------------------- |
427| callback | Callback\<[RichEditorTextSpanResult](#richeditortextspanresult)\> | 是 | [RichEditorTextSpanResult](#richeditortextspanresult)为输入法完成输入后的文本Span信息。<br/>输入法完成输入后的回调。|
428
429### aboutToDelete
430
431aboutToDelete(callback:Callback\<[RichEditorDeleteValue](#richeditordeletevalue), boolean\>)
432
433输入法删除内容前,触发回调。
434
435使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。
436
437**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
438
439**系统能力:** SystemCapability.ArkUI.ArkUI.Full
440
441**参数:**
442
443| 参数名 | 类型                                        | 必填 | 说明                 |
444| ------ | ------------------------------------------- | ---- | -------------------- |
445| callback | Callback\<[RichEditorDeleteValue](#richeditordeletevalue), boolean\> | 是 | [RichEditorDeleteValue](#richeditordeletevalue)为准备删除的内容所在的文本或者图片Span信息。<br/>true:组件执行删除操作。<br/>false:组件不执行删除操作。<br/>输入法删除内容前的回调,英文预上屏点击候选词时会执行该回调。|
446
447### onDeleteComplete
448
449onDeleteComplete(callback:Callback\<void\>)
450
451输入法完成删除后,触发回调。
452
453使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。
454
455**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
456
457**系统能力:** SystemCapability.ArkUI.ArkUI.Full
458
459**参数:**
460
461| 参数名   | 类型                                    | 必填   | 说明        |
462| ----- | --------------------------------------- | ---- | ----------- |
463| callback |Callback\<void\> | 是    | 订阅输入法完成删除的回调。 |
464
465### onPaste<sup>11+</sup>
466
467onPaste(callback: [PasteEventCallback](#pasteeventcallback12) )
468
469完成粘贴前,触发回调。开发者可以通过该方法,覆盖系统默认行为,实现图文的粘贴。
470
471**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
472
473**系统能力:** SystemCapability.ArkUI.ArkUI.Full
474
475**参数:**
476
477| 参数名 | 类型    | 必填 | 说明                          |
478| ------ | ------- | ---- | ----------------------------- |
479| callback | [PasteEventCallback](#pasteeventcallback12) | 是   | 订阅完成粘贴前的回调。 |
480
481### onSelectionChange<sup>12+</sup>
482
483onSelectionChange(callback:Callback\<[RichEditorRange](#richeditorrange)\>)
484
485组件内所有内容选择区域发生变化或编辑状态下光标位置发生变化时触发该回调。光标位置发生变化回调时,选择区域的起始位置等于终止位置。
486
487**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
488
489**系统能力:** SystemCapability.ArkUI.ArkUI.Full
490
491**参数:**
492
493| 参数名   | 类型                                    | 必填   | 说明        |
494| ----- | --------------------------------------- | ---- | ----------- |
495| callback |Callback\<[RichEditorRange](#richeditorrange)\> | 是    | [RichEditorRange](#richeditorrange)为所有内容的选择区域起始和终止位置。<br/>订阅文本选择区域发生变化或编辑状态下光标位置发生变化时触发的回调|
496
497### onEditingChange<sup>12+</sup>
498
499onEditingChange(callback: Callback\<boolean\>)
500
501组件内所有内容的编辑状态发生改变时触发该回调函数。
502
503**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
504
505**系统能力:** SystemCapability.ArkUI.ArkUI.Full
506
507**参数:**
508
509| 参数名   | 类型                                    | 必填   | 说明        |
510| ----- | --------------------------------------- | ---- | ----------- |
511| callback | Callback\<boolean\> | 是    | true表示编辑态,false表示非编辑态。 |
512
513### onSubmit<sup>12+</sup>
514
515onSubmit(callback: SubmitCallback)
516
517按下软键盘输入法回车键触发该回调。
518
519**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
520
521**系统能力:** SystemCapability.ArkUI.ArkUI.Full
522
523**参数:**
524
525| 参数名 | 类型    | 必填 | 说明                          |
526| ------ | ------- | ---- | ----------------------------- |
527| callback | [SubmitCallback](#submitcallback12) | 是   | 侦听事件的回调。 |
528
529### onWillChange<sup>12+</sup>
530
531onWillChange(callback: Callback\<RichEditorChangeValue, boolean\>)
532
533组件执行增删操作前,触发回调。
534
535使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。
536
537**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
538
539**系统能力:** SystemCapability.ArkUI.ArkUI.Full
540
541**参数:**
542
543| 参数名 | 类型 | 必填 | 说明 |
544| -- | -- | -- | -- |
545| callback | Callback\<[RichEditorChangeValue](#richeditorchangevalue12) , boolean\> | 是    | [RichEditorChangeValue](#richeditorchangevalue12)为图文变化信息;boolean表示当前图文是否允许被更改,true:允许图文被更改。false:不允许图文被更改。 |
546
547### onDidChange<sup>12+</sup>
548
549onDidChange(callback: OnDidChangeCallback)
550
551组件执行增删操作后,触发回调。文本实际未发生增删时,不触发该回调。
552
553使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。
554
555**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
556
557**系统能力:** SystemCapability.ArkUI.ArkUI.Full
558
559**参数:**
560
561| 参数名 | 类型 | 必填 | 说明 |
562| -- | -- | -- | -- |
563| callback | [OnDidChangeCallback](ts-text-common.md#ondidchangecallback12) | 是 | 图文变化前后的内容范围。 |
564
565### onCut<sup>12+</sup>
566
567onCut(callback: Callback\<CutEvent\>)
568
569完成剪切前,触发回调。系统的默认剪切行为,只支持纯文本的剪切。开发者可以通过该方法,覆盖系统默认行为,实现图文的剪切。
570
571**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
572
573**系统能力:** SystemCapability.ArkUI.ArkUI.Full
574
575**参数:**
576
577| 参数名   | 类型                                    | 必填   | 说明        |
578| ----- | --------------------------------------- | ---- | ----------- |
579| callback |Callback\<[CutEvent](#cutevent12)\> | 是    | 定义用户剪切事件。 |
580
581### onCopy<sup>12+</sup>
582
583onCopy(callback: Callback\<CopyEvent\>)
584
585完成复制前,触发回调。系统的默认复制行为,只支持纯文本的复制。开发者可以通过该方法,覆盖系统默认行为,实现图文的复制。
586
587**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
588
589**系统能力:** SystemCapability.ArkUI.ArkUI.Full
590
591**参数:**
592
593| 参数名   | 类型                                    | 必填   | 说明        |
594| ----- | --------------------------------------- | ---- | ----------- |
595| callback |Callback\<[CopyEvent](#copyevent12)\> | 是    | 定义用户复制事件。 |
596
597## RichEditorInsertValue
598
599插入文本信息。
600
601**系统能力:** SystemCapability.ArkUI.ArkUI.Full
602
603| 名称           | 类型     | 必填   | 说明         |
604| ------------ | ------ | ---- | ---------- |
605| insertOffset | number | 是    | 插入的文本偏移位置。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
606| insertValue  | string | 是    | 插入的文本内容。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。  |
607| previewText<sup>12+</sup> | string | 否    | 插入的预上屏文本内容。<br/> **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
608
609
610## RichEditorDeleteValue
611
612删除操作的信息和被删除内容的信息。
613
614**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
615
616**系统能力:** SystemCapability.ArkUI.ArkUI.Full
617
618| 名称                    | 类型                                       | 必填   | 说明                  |
619| --------------------- | ---------------------------------------- | ---- | ------------------- |
620| offset                | number                                   | 是    | 删除内容的偏移位置。          |
621| direction             | [RichEditorDeleteDirection](#richeditordeletedirection) | 是    | 删除操作的方向。            |
622| length                | number                                   | 是    | 删除内容长度。             |
623| richEditorDeleteSpans | Array<[RichEditorTextSpanResult](#richeditortextspanresult) \| [RichEditorImageSpanResult](#richeditorimagespanresult)> | 是    | 删除的文本或者图片Span的具体信息。 |
624
625
626## RichEditorDeleteDirection
627
628删除操作的方向。
629
630**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
631
632**系统能力:** SystemCapability.ArkUI.ArkUI.Full
633
634| 名称     | 说明       |
635| -------- | ---------- |
636| BACKWARD | 向后删除。 |
637| FORWARD  | 向前删除。 |
638
639
640## RichEditorTextSpanResult
641
642文本Span信息。
643
644**系统能力:** SystemCapability.ArkUI.ArkUI.Full
645
646| 名称                            | 类型                                       | 必填   | 说明                     |
647| ----------------------------- | ---------------------------------------- | ---- | ---------------------- |
648| spanPosition                  | [RichEditorSpanPosition](#richeditorspanposition) | 是    | Span位置。                <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
649| value                         | string                                   | 是    | 文本Span内容或Symbol的id。              <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
650| textStyle                     | [RichEditorTextStyleResult](#richeditortextstyleresult) | 是    | 文本Span样式信息。            <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
651| offsetInSpan                  | [number, number]                         | 是    | 文本Span内容里有效内容的起始和结束位置。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
652| valueResource<sup>11+</sup>   | [Resource](ts-types.md#resource)         | 否    | 组件SymbolSpan内容。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。        |
653| symbolSpanStyle<sup>11+</sup> | [RichEditorSymbolSpanStyle](#richeditorsymbolspanstyle11) | 否    | 组件SymbolSpan样式信息。      <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
654| paragraphStyle<sup>12+</sup>  | [RichEditorParagraphStyle](#richeditorparagraphstyle11)  | 否   | 段落样式。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
655| previewText<sup>12+</sup>      | string                                   | 否    | 文本Span预上屏内容。              <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
656
657
658## RichEditorSpanPosition
659
660Span位置信息。
661
662**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
663
664**系统能力:** SystemCapability.ArkUI.ArkUI.Full
665
666| 名称        | 类型               | 必填   | 说明                          |
667| --------- | ---------------- | ---- | --------------------------- |
668| spanIndex | number           | 是    | Span索引值。                    |
669| spanRange | [number, number] | 是    | Span内容在RichEditor内的起始和结束位置。 |
670
671## RichEditorSpanType
672
673Span类型信息。
674
675**系统能力:** SystemCapability.ArkUI.ArkUI.Full
676
677| 名称    | 值     | 说明         |
678| ----- | ---- | ------------ |
679| TEXT  | 0 | Span为文字类型。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。  |
680| IMAGE | 1 | Span为图像类型。  <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。   |
681| MIXED | 2 | Span为图文混合类型。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。  |
682| BUILDER<sup>12+</sup> | 3 | Span为BuilderSpan类型。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。  |
683
684## RichEditorResponseType<sup>11+</sup>
685
686菜单的响应类型。
687
688**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
689
690**系统能力:** SystemCapability.ArkUI.ArkUI.Full
691
692| 名称         | 说明          |
693| ---------- | ------------- |
694| LONG_PRESS  | 通过长按触发菜单弹出。   |
695| RIGHT_CLICK | 通过鼠标右键触发菜单弹出。 |
696| SELECT | 通过鼠标选中触发菜单弹出。 |
697
698## RichEditorTextStyleResult
699
700后端返回的文本样式信息。
701
702**系统能力:** SystemCapability.ArkUI.ArkUI.Full
703
704| 名称         | 类型                                       | 必填   | 说明           |
705| ---------- | ---------------------------------------- | ---- | ------------ |
706| fontColor  | [ResourceColor](ts-types.md#resourcecolor) | 是    | 文本颜色。        <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
707| fontSize   | number                                   | 是    | 字体大小,默认单位为fp。        <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
708| fontStyle  | [FontStyle](ts-appendix-enums.md#fontstyle) | 是    | 字体样式。        <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
709| fontWeight | number                                   | 是    | 字体粗细。        <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
710| fontFamily | string                                   | 是    | 字体列表。        <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
711| decoration | [DecorationStyleResult](ts-text-common.md#decorationstyleresult12) | 是    | 文本装饰线样式信息。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
712| textShadow<sup>12+</sup> | &nbsp;Array&lt;[ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions对象说明)> | 否    | 文字阴影效果。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
713| lineHeight<sup>12+</sup> | number       | 否    | 文本行高,默认单位为fp。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
714| letterSpacing<sup>12+</sup>| number       | 否    | 文本字符间距,默认单位为fp。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
715| fontFeature<sup>12+</sup> | string | 否 | 文字特性效果。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
716
717>  **说明:**
718>
719>  在RichEditorTextStyle中,fontWeight是设置字体粗细的输入参数。
720>  而在RichEditorTextStyleResult中,会将之前设置的字体粗细转换为数字后返回。
721>  转换关系如下:
722>
723>  | RichEditorTextStyle中的fontWeight | RichEditorTextStyleResult中的fontWeight |
724>  | ---- | ----------------------------------- |
725>  | 100   | 0 |
726>  | 200   | 1 |
727>  | 300   | 2 |
728>  | 400   | 3 |
729>  | 500   | 4 |
730>  | 600   | 5 |
731>  | 700   | 6 |
732>  | 800   | 7 |
733>  | 900   | 8 |
734>  | Lighter   | 12 |
735>  | Normal   | 10 |
736>  | Regular   | 14 |
737>  | Medium   | 13 |
738>  | Bold   | 9 |
739>  | Bolder   | 11 |
740>
741>  RichEditorSymbolSpanStyle和RichEditorSymbolSpanStyleResult中fontWeight的转换关系,
742>  与RichEditorTextStyle和RichEditorTextStyleResult中fontWeight的转换关系一致。
743
744## RichEditorSymbolSpanStyleResult<sup>11+</sup>
745
746后端返回的SymbolSpan样式信息。
747
748**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
749
750**系统能力:** SystemCapability.ArkUI.ArkUI.Full
751
752| 名称 | 类型 | 必填 | 说明                               |
753| ------ | -------- | ---- | -------------------------------------- |
754| fontColor | Array\<[ResourceColor](ts-types.md#resourcecolor)\> | 是 | SymbolSpan组件颜色。<br/> 默认值:不同渲染策略下默认值不同。 |
755| fontSize | number \| string \| [Resource](ts-types.md#resource) | 是 | SymbolSpan组件大小,默认单位为fp。<br/>默认值:跟随主题。|
756| fontWeight | number \| [FontWeight](ts-appendix-enums.md#fontweight) \| string  | 是 | SymbolSpan组件粗细。<br/>number类型取值[100,900],取值间隔为100,默认为400,取值越大,字体越粗。<br/>string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular” 、“medium”分别对应FontWeight中相应的枚举值。<br/>默认值:FontWeight.Normal。|
757| renderingStrategy | [SymbolRenderingStrategy](ts-basic-components-symbolGlyph.md#symbolrenderingstrategy11枚举说明)	| 是 | SymbolSpan组件渲染策略。<br/>默认值:SymbolRenderingStrategy.SINGLE。|
758| effectStrategy | [SymbolEffectStrategy](ts-basic-components-symbolGlyph.md#symboleffectstrategy11枚举说明)	| 是 | SymbolSpan组件动效策略。<br/>默认值:SymbolEffectStrategy.NONE。|
759
760## RichEditorImageSpanResult
761
762后端返回的图片信息。
763
764**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
765
766**系统能力:** SystemCapability.ArkUI.ArkUI.Full
767
768| 名称               | 类型                                                                | 必填  | 说明               |
769|------------------|-------------------------------------------------------------------|-----|------------------|
770| spanPosition     | [RichEditorSpanPosition](#richeditorspanposition)                 | 是   | Span位置。|
771| valuePixelMap    | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7)                    | 否   | 图片内容。|
772| valueResourceStr | [ResourceStr](ts-types.md#resourcestr)                            | 否   | 图片资源id。|
773| imageStyle       | [RichEditorImageSpanStyleResult](#richeditorimagespanstyleresult) | 是 | 图片样式。|
774| offsetInSpan     | [number, number] | 是 | Span里图片的起始和结束位置。|
775
776## RichEditorImageSpanStyleResult
777
778后端返回的图片样式信息。
779
780**系统能力:** SystemCapability.ArkUI.ArkUI.Full
781
782| 名称            | 类型                                       | 必填   | 说明        |
783| ------------- | ---------------------------------------- | ---- | --------- |
784| size          | [number, number]                         | 是    | 图片的宽度和高度,单位为px。默认值:size的默认值与objectFit的值有关,不同的objectFit值对应的size默认值也不同。objectFit的值为Cover时,图片高度为组件高度减去组件上下内边距,图片宽度为组件宽度减去组件左右内边距。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
785| verticalAlign | [ImageSpanAlignment](ts-basic-components-imagespan.md#imagespanalignment) | 是    | 图片垂直对齐方式。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
786| objectFit     | [ImageFit](ts-appendix-enums.md#imagefit) | 是    | 图片缩放类型。   <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
787| layoutStyle<sup>12+</sup> | [RichEditorLayoutStyle](#richeditorlayoutstyle11)     | 否   | 图片布局风格。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 ||
788
789## RichEditorLayoutStyle<sup>11+</sup>
790
791**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
792
793**系统能力:** SystemCapability.ArkUI.ArkUI.Full
794
795|名称	|类型	|必填|	说明|
796| -------------  | -----------------------            | ---- | ------------------------------------------------------------ |
797|margin	         |  [Dimension](ts-types.md#dimension10) \| [Margin](ts-types.md#margin)	                       |  否  |	外边距类型,用于描述组件不同方向的外边距。<br/>参数为Dimension类型时,四个方向外边距同时生效。|
798|borderRadius	   |  [Dimension](ts-types.md#dimension10) \| [BorderRadiuses](ts-types.md#borderradiuses9)  |  否  |	圆角类型,用于描述组件边框圆角半径。<br/>参数为Dimension类型时,不支持以Percentage形式设置。|
799
800## RichEditorOptions
801
802RichEditor初始化参数。
803
804**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
805
806**系统能力:** SystemCapability.ArkUI.ArkUI.Full
807
808| 名称         | 类型                                       | 必填   | 说明      |
809| ---------- | ---------------------------------------- | ---- | ------- |
810| controller | [RichEditorController](#richeditorcontroller) | 是    | 富文本控制器。 |
811
812## RichEditorStyledStringOptions<sup>12+</sup>
813
814RichEditor初始化参数。
815
816**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
817
818**系统能力:** SystemCapability.ArkUI.ArkUI.Full
819
820| 名称         | 类型                                       | 必填   | 说明      |
821| ---------- | ---------------------------------------- | ---- | ------- |
822| controller | [RichEditorStyledStringController](#richeditorstyledstringcontroller12) | 是    | 富文本控制器。 |
823
824## RichEditorChangeValue<sup>12+</sup>
825
826**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
827
828**系统能力:** SystemCapability.ArkUI.ArkUI.Full
829
830| 名称                    | 类型                                       | 必填   | 说明                  |
831| --------------------- | ---------------------------------------- | ---- | ------------------- |
832| rangeBefore | [TextRange](ts-universal-attributes-text-style.md#textrange12) | 是    | 即将被替换内容的开始和结束索引。 |
833| replacedSpans | Array<[RichEditorTextSpanResult](#richeditortextspanresult)> | 是    | 替换后文本Span的具体信息。 |
834| replacedImageSpans | Array<[RichEditorImageSpanResult](#richeditorimagespanresult)> | 是    | 替换后ImageSpan的具体信息。 |
835| replacedSymbolSpans | Array<[RichEditorTextSpanResult](#richeditortextspanresult)> | 是    | 替换后SymbolSpan的具体信息。 |
836
837## RichEditorBaseController<sup>12+</sup>
838
839RichEditor组件控制器基类。
840
841### getCaretOffset<sup>10+</sup>
842
843getCaretOffset(): number
844
845返回当前光标所在位置。
846
847**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
848
849**系统能力:** SystemCapability.ArkUI.ArkUI.Full
850
851**返回值:**
852
853| 类型     | 说明        |
854| ------ | --------- |
855| number | 当前光标所在位置。 |
856
857### setCaretOffset<sup>10+</sup>
858
859setCaretOffset(offset: number): boolean
860
861设置光标位置。
862
863**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
864
865**系统能力:** SystemCapability.ArkUI.ArkUI.Full
866
867**参数:**
868
869| 参数名    | 类型   | 必填   | 说明                 |
870| ------ | ------ | ---- | -------------------- |
871| offset | number | 是    | 光标偏移位置。超出所有内容范围时,设置失败。 |
872
873**返回值:**
874
875| 类型      | 说明        |
876| ------- | --------- |
877| boolean | 光标是否设置成功。 |
878
879### closeSelectionMenu<sup>10+</sup>
880
881closeSelectionMenu(): void
882
883关闭自定义选择菜单或系统默认选择菜单。
884
885**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
886
887**系统能力:** SystemCapability.ArkUI.ArkUI.Full
888
889### getTypingStyle<sup>11+</sup>
890
891getTypingStyle(): RichEditorTextStyle
892
893获得用户预设的样式。
894
895**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
896
897**系统能力:** SystemCapability.ArkUI.ArkUI.Full
898
899**返回值:**
900
901| 类型                                       | 说明      |
902| ---------------------------------------- | ------- |
903| [RichEditorTextStyle](#richeditortextstyle) | 用户预设样式。 |
904
905### setTypingStyle<sup>11+</sup>
906
907setTypingStyle(value: RichEditorTextStyle): void
908
909设置用户预设的样式。
910
911**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
912
913**系统能力:** SystemCapability.ArkUI.ArkUI.Full
914
915**参数:**
916
917| 参数名   | 类型                                     | 必填   | 说明  |
918| ----- | ---------------------------------------- | ---- | ----- |
919| value | [RichEditorTextStyle](#richeditortextstyle) | 是    | 预设样式。 |
920
921### setSelection<sup>11+</sup>
922
923setSelection(selectionStart:&nbsp;number, selectionEnd:&nbsp;number, options?:&nbsp;SelectionOptions): void
924
925支持设置组件内的内容选中,选中部分背板高亮。
926
927selectionStart和selectionEnd均为-1时表示全选。
928
929未获焦时调用该接口不产生选中效果。
930
931从API version 12开始,在2in1设备中,无论options取何值,调用setSelection接口都不会弹出菜单,此外,如果组件中已经存在菜单,调用setSelection接口会关闭菜单。
932
933在非2in1设备中,options取值为MenuPolicy.DEFAULT时,遵循以下规则:
934
9351. 组件内有手柄菜单时,接口调用后不关闭菜单,并且调整菜单位置。
936
9372. 组件内有不带手柄的菜单时,接口调用后不关闭菜单,并且菜单位置不变。
938
9393. 组件内无菜单时,接口调用后也无菜单显示。
940
941**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
942
943**系统能力:** SystemCapability.ArkUI.ArkUI.Full
944
945**参数:**
946
947| 参数名            | 类型   | 必填   | 说明    |
948| -------------- | ------ | ---- | ------- |
949| selectionStart | number | 是    | 选中开始位置。 |
950| selectionEnd   | number | 是    | 选中结束位置。 |
951| options<sup>12+</sup>   | [SelectionOptions](ts-types.md#selectionoptions12对象说明) | 否    | 选择项配置。 |
952
953### isEditing<sup>12+</sup>
954
955isEditing(): boolean
956
957获取当前富文本的编辑状态。
958
959**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
960
961**系统能力:** SystemCapability.ArkUI.ArkUI.Full
962
963**返回值:**
964
965| 类型    | 说明                          |
966| ------- | ----------------------------- |
967| boolean | true为编辑态,false为非编辑态。 |
968
969### stopEditing<sup>12+</sup>
970
971stopEditing(): void
972
973退出编辑态。
974
975**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
976
977**系统能力:** SystemCapability.ArkUI.ArkUI.Full
978
979### getLayoutManager<sup>12+</sup>
980
981getLayoutManager(): LayoutManager
982
983获取布局管理器对象。
984
985**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
986
987**系统能力:** SystemCapability.ArkUI.ArkUI.Full
988
989**返回值:**
990
991| 类型                                       | 说明      |
992| ---------------------------------------- | ------- |
993| [LayoutManager](ts-text-common.md#LayoutManager12) | 布局管理器对象。 |
994
995### getPreviewText<sup>12+</sup>
996
997getPreviewText(): PreviewText
998
999获取预上屏信息。
1000
1001**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1002
1003**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1004
1005**返回值:**
1006
1007| 类型                                       | 说明      |
1008| ---------------------------------------- | ------- |
1009| [PreviewText](ts-text-common.md#previewtext12) | 预上屏信息。 |
1010
1011## RichEditorController
1012
1013RichEditor组件的控制器,继承自[RichEditorBaseController](#richeditorbasecontroller12)。
1014
1015### 导入对象
1016
1017```
1018controller: RichEditorController = new RichEditorController()
1019```
1020
1021### addTextSpan
1022
1023addTextSpan(value: string, options?: RichEditorTextSpanOptions): number
1024
1025添加文本内容,如果组件光标闪烁,插入后光标位置更新为新插入文本的后面。
1026
1027**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1028
1029**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1030
1031**参数:**
1032
1033| 参数名     | 类型                                     | 必填   | 说明  |
1034| ------- | ---------------------------------------- | ---- | ----- |
1035| value   | string                                   | 是    | 文本内容。 |
1036| options | [RichEditorTextSpanOptions](#richeditortextspanoptions) | 否    | 文本选项。 |
1037
1038**返回值:**
1039
1040| 类型     | 说明                   |
1041| ------ | -------------------- |
1042| number | 添加完成的TextSpan所在的位置。 |
1043
1044### addImageSpan
1045
1046addImageSpan(value: PixelMap | ResourceStr, options?: RichEditorImageSpanOptions): number
1047
1048添加图片内容,如果组件光标闪烁,插入后光标位置更新为新插入图片的后面。
1049
1050不建议直接添加网络图片。
1051
1052**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1053
1054**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1055
1056**参数:**
1057
1058| 参数名     | 类型                                     | 必填   | 说明  |
1059| ------- | ---------------------------------------- | ---- | ----- |
1060| value   | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7)\|[ResourceStr](ts-types.md#resourcestr) | 是    | 图片内容。 |
1061| options | [RichEditorImageSpanOptions](#richeditorimagespanoptions) | 否    | 图片选项。 |
1062
1063**返回值:**
1064
1065| 类型     | 说明                   |
1066| ------ | -------------------- |
1067| number | 添加完成的ImageSpan所在的位置。 |
1068
1069### addBuilderSpan<sup>11+</sup>
1070
1071addBuilderSpan(value: CustomBuilder, options?: RichEditorBuilderSpanOptions): number
1072
1073添加用户自定义布局Span。
1074
1075> **说明:**
1076>
1077> - RichEditor组件添加占位Span,占位Span调用系统的measure方法计算真实的长宽和位置。
1078> - 可通过[RichEditorBuilderSpanOptions](#richeditorbuilderspanoptions11)设置此builder在RichEditor中的index(一个文字为一个单位)。
1079> - 此占位Span不可获焦,支持拖拽,支持部分通用属性,占位、删除等能力等同于ImageSpan,长度视为一个文字。
1080> - 不支持通过[bindSelectionMenu](#bindselectionmenu)设置自定义菜单。
1081> - 不支持通过[getSpans](#getspans),[getSelection](#getselection11),[onSelect](#onselect),[aboutToDelete](#abouttodelete)获取builderSpan信息。
1082> - 不支持通过[updateSpanStyle](#updatespanstyle),[updateParagraphStyle](#updateparagraphstyle11)等方式更新builder。
1083> - 对此builder节点进行复制或粘贴不生效。
1084> - builder的布局约束由RichEditor传入,如果builder里最外层组件不设置大小,则会用RichEditor的大小作为maxSize。
1085> - builder的手势相关事件机制与通用手势事件相同,如果builder中未设置透传,则仅有builder中的子组件响应。
1086> - 如果组件光标闪烁,插入后光标位置更新为新插入builder的后面。
1087
1088通用属性仅支持[size](ts-universal-attributes-size.md#size)、[padding](ts-universal-attributes-size.md#padding)、[margin](ts-universal-attributes-size.md#margin)、[aspectRatio](ts-universal-attributes-layout-constraints.md#aspectratio)、[borderStyle](ts-universal-attributes-border.md#borderstyle)、[borderWidth](ts-universal-attributes-border.md#borderwidth)、[borderColor](ts-universal-attributes-border.md#bordercolor)、[borderRadius](ts-universal-attributes-border.md#borderradius)、[backgroundColor](ts-universal-attributes-background.md#backgroundcolor)、[backgroundBlurStyle](ts-universal-attributes-background.md#backgroundblurstyle9)、[opacity](ts-universal-attributes-opacity.md)、[blur](ts-universal-attributes-image-effect.md#blur)、[backdropBlur](ts-universal-attributes-background.md#backdropblur)、[shadow](ts-universal-attributes-image-effect.md#shadow)、[grayscale](ts-universal-attributes-image-effect.md#grayscale)、[brightness](ts-universal-attributes-image-effect.md#brightness)、[saturate](ts-universal-attributes-image-effect.md#saturate)、
1089[contrast](ts-universal-attributes-image-effect.md#contrast)、[invert](ts-universal-attributes-image-effect.md#invert)、[sepia](ts-universal-attributes-image-effect.md#sepia)、[hueRotate](ts-universal-attributes-image-effect.md#huerotate)、[colorBlend](ts-universal-attributes-image-effect.md#colorblend7)、[linearGradientBlur](ts-universal-attributes-image-effect.md#lineargradientblur12)、[clip](ts-universal-attributes-sharp-clipping.md#clip)、[mask](ts-universal-attributes-sharp-clipping.md#mask)、[foregroundBlurStyle](ts-universal-attributes-foreground-blur-style.md#foregroundblurstyle)、[accessibilityGroup](ts-universal-attributes-accessibility.md#accessibilitygroup)、[accessibilityText](ts-universal-attributes-accessibility.md#accessibilitytext)、[accessibilityDescription](ts-universal-attributes-accessibility.md#accessibilitydescription)、[accessibilityLevel](ts-universal-attributes-accessibility.md#accessibilitylevel)、[sphericalEffect](ts-universal-attributes-image-effect.md#sphericaleffect12)、[lightUpEffect](ts-universal-attributes-image-effect.md#lightupeffect12)、[pixelStretchEffect](ts-universal-attributes-image-effect.md#pixelstretcheffect12)。
1090
1091**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1092
1093**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1094
1095**参数:**
1096
1097| 参数名     | 类型                                     | 必填   | 说明       |
1098| ------- | ---------------------------------------- | ---- | ---------- |
1099| value   | [CustomBuilder](ts-types.md#custombuilder8) | 是    | 自定义组件。     |
1100| options | [RichEditorBuilderSpanOptions](#richeditorbuilderspanoptions11) | 否    | builder选项。 |
1101
1102**返回值:**
1103
1104| 类型     | 说明                     |
1105| ------ | ---------------------- |
1106| number | 添加完成的builderSpan所在的位置。 |
1107
1108### addSymbolSpan<sup>11+</sup>
1109
1110addSymbolSpan(value: Resource, options?: RichEditorSymbolSpanOptions ): number
1111
1112在Richeditor中添加SymbolSpan,如果组件光标闪烁,插入后光标位置更新为新插入Symbol的后面。
1113
1114暂不支持手势、复制、拖拽处理。
1115
1116**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1117
1118**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1119
1120**参数:**
1121
1122| 参数名     | 类型                                     | 必填   | 说明  |
1123| ------- | ---------------------------------------- | ---- | ----- |
1124| value   | [Resource](ts-types.md#resource)         | 是    | 组件内容。 |
1125| options | [RichEditorSymbolSpanOptions](#richeditorsymbolspanoptions11) | 否    | 组件选项。 |
1126
1127**返回值:**
1128
1129| 类型     | 说明                    |
1130| ------ | --------------------- |
1131| number | 添加完成的SymbolSpan所在的位置。 |
1132
1133### updateSpanStyle
1134
1135updateSpanStyle(value: RichEditorUpdateTextSpanStyleOptions | RichEditorUpdateImageSpanStyleOptions | RichEditorUpdateSymbolSpanStyleOptions): void
1136
1137更新文本、图片或SymbolSpan样式。<br/>若只更新了一个Span的部分内容,则会根据更新部分、未更新部分将该Span拆分为多个Span。
1138
1139使用该接口更新文本、图片或SymbolSpan样式时默认不会关闭自定义文本选择菜单。
1140
1141**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1142
1143**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1144
1145**参数:**
1146
1147| 参数名 | 类型 | 必填 | 说明                               |
1148| ------ | -------- | ---- | -------------------------------------- |
1149| value | [RichEditorUpdateTextSpanStyleOptions](#richeditorupdatetextspanstyleoptions) \| [RichEditorUpdateImageSpanStyleOptions](#richeditorupdateimagespanstyleoptions) \| [RichEditorUpdateSymbolSpanStyleOptions](#richeditorupdatesymbolspanstyleoptions11) | 是 | 文本、图片或SymbolSpan的样式选项信息。 |
1150
1151>  **说明:**
1152>
1153>  当start大于end时为异常情况,此时start为0,end为无穷大。
1154
1155### updateParagraphStyle<sup>11+</sup>
1156
1157updateParagraphStyle(value: RichEditorParagraphStyleOptions): void
1158
1159更新段落的样式。
1160
1161**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1162
1163**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1164
1165**参数:**
1166
1167| 参数名    | 类型                                       | 必填   | 说明         |
1168| ----- | ---------------------------------------- | ---- | ---------- |
1169| value | [RichEditorParagraphStyleOptions](#richeditorparagraphstyleoptions11) | 是    | 段落的样式选项信息。 |
1170
1171### getSpans
1172
1173getSpans(value?: RichEditorRange): Array<RichEditorImageSpanResult| RichEditorTextSpanResult>
1174
1175获取span信息。
1176
1177**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1178
1179**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1180
1181**参数:**
1182
1183| 参数名   | 类型                                | 必填   | 说明        |
1184| ----- | ----------------------------------- | ---- | ----------- |
1185| value | [RichEditorRange](#richeditorrange) | 否    | 需要获取span范围。 |
1186
1187**返回值:**
1188
1189| 类型                                       | 说明           |
1190| ---------------------------------------- | ------------ |
1191| Array<[RichEditorTextSpanResult](#richeditortextspanresult) \| [RichEditorImageSpanResult](#richeditorimagespanresult)> | 文本和图片Span信息。 |
1192
1193### deleteSpans
1194
1195deleteSpans(value?: RichEditorRange): void
1196
1197删除指定范围内的文本和图片。
1198
1199**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1200
1201**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1202
1203**参数:**
1204
1205| 参数名   | 类型                                | 必填   | 说明                |
1206| ----- | ----------------------------------- | ---- | ------------------- |
1207| value | [RichEditorRange](#richeditorrange) | 否    | 删除范围。省略时,删除所有文本和图片。 |
1208
1209### getParagraphs<sup>11+</sup>
1210
1211getParagraphs(value?: RichEditorRange): Array\<RichEditorParagraphResult>
1212
1213获得指定返回的段落。
1214
1215**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1216
1217**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1218
1219**参数:**
1220
1221| 参数名   | 类型                                | 必填   | 说明       |
1222| ----- | ----------------------------------- | ---- | ---------- |
1223| value | [RichEditorRange](#richeditorrange) | 否    | 需要获取段落的范围。 |
1224
1225**返回值:**
1226
1227| 类型                                       | 说明       |
1228| ---------------------------------------- | -------- |
1229| Array\<[RichEditorParagraphResult](#richeditorparagraphresult11)> | 选中段落的信息。 |
1230
1231### getSelection<sup>11+</sup>
1232
1233getSelection(): RichEditorSelection
1234
1235获取选中内容。如果未选中内容,返回光标所在span信息。
1236
1237**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1238
1239**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1240
1241**返回值:**
1242
1243| 类型                                       | 说明      |
1244| ---------------------------------------- | ------- |
1245| [RichEditorSelection](#richeditorselection) | 选中内容信息。 |
1246
1247### fromStyledString<sup>12+</sup>
1248
1249fromStyledString(value: StyledString): Array\<RichEditorSpan>
1250
1251将属性字符串转换成span信息。
1252
1253**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1254
1255**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1256
1257**参数:**
1258
1259| 参数名   | 类型                                | 必填   | 说明       |
1260| ----- | ----------------------------------- | ---- | ---------- |
1261| value | [StyledString](ts-universal-styled-string.md#styledstring) | 是    | 转换前的属性字符串。 |
1262
1263**返回值:**
1264
1265| 类型                                       | 说明      |
1266| ---------------------------------------- | ------- |
1267| Array<[RichEditorSpan](#richeditorspan12)>  | 文本和图片Span信息。 |
1268
1269**错误码:**
1270
1271以下错误码详细介绍请参考[通用错误码](../../errorcode-universal.md)。
1272
1273| 错误码ID | 错误信息                        |
1274| -------- | ------------------------------ |
1275| 401      | The parameter check failed.  |
1276
1277### toStyledString<sup>12+</sup>
1278
1279toStyledString(value: RichEditorRange): StyledString
1280
1281将给定范围的组件内容转换成属性字符串。
1282
1283**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1284
1285**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1286
1287**参数:**
1288
1289| 参数名   | 类型                                | 必填   | 说明       |
1290| ----- | ----------------------------------- | ---- | ---------- |
1291| value | [RichEditorRange](#richeditorrange) | 是    | 需要获取的范围。 |
1292
1293**返回值:**
1294
1295| 类型                                       | 说明       |
1296| ---------------------------------------- | -------- |
1297| [StyledString](ts-universal-styled-string.md#styledstring) | 转换后的属性字符串 |
1298
1299**错误码:**
1300
1301以下错误码详细介绍请参考[通用错误码](../../errorcode-universal.md)。
1302
1303| 错误码ID | 错误信息                        |
1304| -------- | ------------------------------ |
1305| 401      | The parameter check failed.  |
1306
1307## RichEditorStyledStringController<sup>12+</sup>
1308
1309使用属性字符串构建的RichEditor组件的控制器,继承自[RichEditorBaseController](#richeditorbasecontroller12)。
1310
1311### 导入对象
1312
1313```
1314controller: RichEditorStyledStringController = new RichEditorStyledStringController()
1315```
1316
1317### getSelection<sup>12+</sup>
1318
1319getSelection(): RichEditorRange
1320
1321获取当前富文本当前的选中区域范围。
1322
1323**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1324
1325**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1326
1327**返回值:**
1328
1329| 类型                                       | 说明      |
1330| ---------------------------------------- | ------- |
1331| [RichEditorRange](#richeditorrange) | 选中区域范围。 |
1332
1333### setStyledString<sup>12+</sup>
1334
1335setStyledString(styledString: StyledString): void
1336
1337设置富文本组件显示的属性字符串。
1338
1339**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1340
1341**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1342
1343**参数:**
1344
1345| 参数名   | 类型   | 必填   | 说明                |
1346| ----- | ------ | ---- | ------------------- |
1347| styledString | [StyledString](ts-universal-styled-string.md#styledstring) | 是    | 属性字符串。<br/>**说明:** <br/>StyledString的子类[MutableStyledString](ts-universal-styled-string.md#mutablestyledstring)也可以作为入参值。 |
1348
1349### getStyledString<sup>12+</sup>
1350
1351getStyledString(): MutableStyledString;
1352
1353获取富文本组件显示的属性字符串。
1354
1355**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1356
1357**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1358
1359**返回值:**
1360
1361| 类型    | 说明                          |
1362| ------- | ----------------------------- |
1363| [MutableStyledString](ts-universal-styled-string.md#mutablestyledstring) | 富文本组件显示的属性字符串 |
1364
1365### onContentChanged<sup>12+</sup>
1366
1367onContentChanged(listener: StyledStringChangedListener): void
1368
1369注册文本内容变化回调,该回调会在后端程序导致文本内容变更时触发
1370
1371**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1372
1373**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1374
1375**参数:**
1376
1377| 参数名   | 类型   | 必填   | 说明                |
1378| ----- | ------ | ---- | ------------------- |
1379| listener | [StyledStringChangedListener](ts-text-common.md#styledstringchangedlistener12) | 是    | 文本内容变化回调监听器。 |
1380
1381## RichEditorSelection
1382
1383选中内容信息。
1384
1385**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1386
1387**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1388
1389| 名称        | 类型                                       | 必填   | 说明      |
1390| --------- | ---------------------------------------- | ---- | ------- |
1391| selection | [number, number]                         | 是    | 选中范围。   |
1392| spans     | Array<[RichEditorTextSpanResult](#richeditortextspanresult)\| [RichEditorImageSpanResult](#richeditorimagespanresult)> | 是    | span信息。 |
1393
1394## RichEditorRange
1395
1396定义RichEditor的范围。
1397
1398继承自[RichEditorRange](#richeditorrange)。
1399
1400**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1401
1402**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1403
1404| 名称  | 类型   | 必填 | 说明                                                         |
1405| ----- | ------ | ---- | ------------------------------------------------------------ |
1406| start | number | 否   | 需要更新样式的文本起始位置,省略或者设置负值时表示从0开始。  |
1407| end   | number | 否   | 需要更新样式的文本结束位置,省略或者超出文本范围时表示无穷大。 |
1408
1409
1410## RichEditorSpanStyleOptions
1411
1412文本样式选项。
1413
1414继承自[RichEditorRange](#richeditorrange)。
1415
1416**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1417
1418**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1419
1420## RichEditorUpdateTextSpanStyleOptions
1421
1422文本样式选项。
1423
1424继承自[RichEditorSpanStyleOptions](#richeditorspanstyleoptions)。
1425
1426**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1427
1428**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1429
1430| 名称      | 类型                                        | 必填 | 说明       |
1431| --------- | ------------------------------------------- | ---- | ---------- |
1432| textStyle | [RichEditorTextStyle](#richeditortextstyle) | 是   | 文本样式。 |
1433
1434## RichEditorUpdateImageSpanStyleOptions
1435
1436图片样式选项。
1437
1438继承自[RichEditorSpanStyleOptions](#richeditorspanstyleoptions)。
1439
1440**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1441
1442**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1443
1444| 名称         | 类型                                       | 必填   | 说明                              |
1445| ---------- | ---------------------------------------- | ---- | ------------------------------- |
1446| imageStyle | [RichEditorImageSpanStyle](#richeditorimagespanstyle) | 是    | 图片样式。                           |
1447
1448## RichEditorUpdateSymbolSpanStyleOptions<sup>11+</sup>
1449
1450SymbolSpan样式选项。
1451
1452继承自[RichEditorSpanStyleOptions](#richeditorspanstyleoptions)。
1453
1454**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1455
1456**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1457
1458| 名称        | 类型                                                      | 必填 | 说明       |
1459| ----------- | --------------------------------------------------------- | ---- | ---------- |
1460| symbolStyle | [RichEditorSymbolSpanStyle](#richeditorsymbolspanstyle11) | 是   | 组件样式。 |
1461
1462## RichEditorParagraphStyleOptions<sup>11+</sup>
1463
1464段落样式选项。
1465
1466继承自[RichEditorSpanStyleOptions](#richeditorspanstyleoptions)。
1467
1468**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1469
1470**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1471
1472| 名称    | 类型                                       | 必填   | 说明                                 |
1473| ----- | ---------------------------------------- | ---- | ---------------------------------- |
1474| style | [RichEditorParagraphStyle](#richeditorparagraphstyle11) | 是    | 段落样式。                              |
1475
1476>  **说明:**
1477>
1478>  接口作用的范围:设定的区间所涉及的段落。
1479
1480## RichEditorParagraphStyle<sup>11+</sup>
1481
1482段落样式。
1483
1484**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1485
1486**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1487
1488| 名称            | 类型                                       | 必填   | 说明                 |
1489| ------------- | ---------------------------------------- | ---- | ------------------ |
1490| textAlign     | [TextAlign](ts-appendix-enums.md#textalign) | 否    | 设置文本段落在水平方向的对齐方式。默认值:TextAlign.START  <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1491| leadingMargin | [Dimension](ts-types.md#dimension10) \| [LeadingMarginPlaceholder](#leadingmarginplaceholder11) | 否    | 设置文本段落缩进,当段落仅存在ImageSpan或BuilderSpan时,此属性值不生效。参数为Dimension类型时,不支持以Percentage形式设置。默认值:{"size":["0.00px","0.00px"]} <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1492| wordBreak<sup>12+</sup> |  [WordBreak](ts-appendix-enums.md#wordbreak11) | 否    | 设置断行规则。 <br />默认值:WordBreak.BREAK_WORD  |
1493| lineBreakStrategy<sup>12+</sup> | [LineBreakStrategy](ts-appendix-enums.md#linebreakstrategy12) | 否 | 设置折行规则。 <br />默认值:LineBreakStrategy.GREEDY<br />在wordBreak不等于breakAll的时候生效,不支持连字符。 |
1494
1495## LeadingMarginPlaceholder<sup>11+</sup>
1496
1497前导边距占位符,用于表示文本段落左侧与组件边缘之间的距离。
1498
1499**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1500
1501| 名称       | 类型                                       | 必填   | 说明             |
1502| -------- | ---------------------------------------- | ---- | -------------- |
1503| pixelMap | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7) | 是    | 图片内容。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1504| size     | \[[Dimension](ts-types.md#dimension10), [Dimension](ts-types.md#dimension10)\] | 是    | 图片大小,不支持设置百分比。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
1505
1506## RichEditorParagraphResult<sup>11+</sup>
1507
1508后端返回的段落信息。
1509
1510**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1511
1512**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1513
1514| 名称    | 类型                                       | 必填   | 说明      |
1515| ----- | ---------------------------------------- | ---- | ------- |
1516| style | [RichEditorParagraphStyle](#richeditorparagraphstyle11) | 是    | 段落样式。   |
1517| range | \[number, number\]                       | 是    | 段落起始和结束位置。 |
1518
1519## RichEditorTextSpanOptions
1520
1521添加文本的偏移位置和文本样式信息。
1522
1523**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1524
1525| 名称                           | 类型                                       | 必填   | 说明                         |
1526| ---------------------------- | ---------------------------------------- | ---- | -------------------------- |
1527| offset                       | number                                   | 否    | 添加文本的位置。省略时,添加到所有内容的最后。<br/>当值小于0时,放在所有内容最前面;当值大于所有内容长度时,放在所有内容最后面。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1528| style                        | [RichEditorTextStyle](#richeditortextstyle) | 否    | 文本样式信息。省略时,使用系统默认文本信息。     <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1529| paragraphStyle<sup>11+</sup> | [RichEditorParagraphStyle](#richeditorparagraphstyle11) | 否    | 段落样式。                     <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
1530| gesture<sup>11+</sup>        | [RichEditorGesture](#richeditorgesture11) | 否    | 行为触发回调。省略时,仅使用系统默认行为。      <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1531
1532## RichEditorTextStyle
1533
1534文本样式信息。
1535
1536**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1537
1538| 名称                       | 类型                                       | 必填   | 说明                                       |
1539| ------------------------ | ---------------------------------------- | ---- | ---------------------------------------- |
1540| fontColor                | [ResourceColor](ts-types.md#resourcecolor) | 否    | 文本颜色。<br/> 默认值:$r('sys.color.font_primary')。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1541| fontSize                 | [Length](ts-types.md#length) \| number            | 否    | 设置字体大小,Length为number类型时,使用fp单位。字体默认大小16。不支持设置百分比字符串。字体大小设置为0时,显示默认字体大小。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1542| fontStyle                | [FontStyle](ts-appendix-enums.md#fontstyle) | 否    | 字体样式。<br/>默认值:FontStyle.Normal。          <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1543| fontWeight               |  number \|  [FontWeight](ts-appendix-enums.md#fontweight) \| string | 否    | 字体粗细。<br/>number类型取值[100,900],取值间隔为100,默认为400,取值越大,字体越粗。<br/>string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular” 、“medium”分别对应FontWeight中相应的枚举值。<br/>默认值:FontWeight.Normal。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1544| fontFamily               | [ResourceStr](ts-types.md#resourcestr) | 否    | 设置字体列表。默认字体'HarmonyOS Sans',当前支持'HarmonyOS Sans'字体和[注册自定义字体](../js-apis-font.md)。 <br/>默认字体:'HarmonyOS Sans'。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1545| decoration               | [DecorationStyleInterface](ts-universal-styled-string.md#decorationstyleinterface对象说明) | 否    | 设置文本装饰线样式及其颜色。<br/>type默认值:TextDecorationType.None。<br/>color默认值:跟随字体颜色。<br/>style默认值:TextDecorationStyle.SOLID。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1546| textShadow<sup>11+</sup> | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions对象说明)&nbsp;\|&nbsp;Array&lt;[ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions对象说明)> | 否    | 设置文字阴影效果。该接口支持以数组形式入参,实现多重文字阴影。<br/>**说明:**<br/>仅支持设置阴影模糊半径、阴影的颜色、阴影的偏移量。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1547| lineHeight<sup>12+</sup>    | number \| string \| [Resource](ts-types.md#resource) | 否     |设置文本的文本行高,设置值不大于0时,不限制文本行高,自适应字体大小,number类型时单位为fp,不支持设置百分比字符串。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1548| letterSpacing<sup>12+</sup> | number \| string             | 否     | 设置文本字符间距,当取值为负值时,文字会发生压缩,负值过小时会将组件内容区大小压缩为0,导致无内容显示,number类型时单位为fp, 不支持设置百分比字符串。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1549| fontFeature<sup>12+</sup> | string | 否 | 设置文字特性效果,比如数字等宽的特性。如果未设置,默认为变宽数字。设置无效字符保持默认。<br/>格式为:normal \| \<feature-tag-value\><br/>\<feature-tag-value\>的格式为:\<string\> \[ \<integer\> \| on \| off ]<br/>\<feature-tag-value\>的个数可以有多个,中间用','隔开。<br/>例如,使用等宽时钟数字的输入格式为:"ss01" on。<br/>Font Feature当前支持的属性见 [fontFeature属性列表](ts-basic-components-text.md#fontfeature12)。<br/>设置 Font Feature 属性,Font Feature 是 OpenType 字体的高级排版能力,如支持连字、数字等宽等特性,一般用在自定义字体中,其能力需要字体本身支持。<br/>更多 Font Feature 能力介绍可参考 https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prophttps://sparanoid.com/lab/opentype-features/<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1550
1551## PlaceholderStyle<sup>12+</sup>
1552
1553添加提示文本的字体样式。
1554
1555**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1556
1557**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1558
1559| 名称                           | 类型                                       | 必填   | 说明                         |
1560| ---------------------------- | ---------------------------------------- | ---- | -------------------------- |
1561| font                         | [Font](ts-types.md#font)                    | 否    | 设置placeholder文本样式。<br/>默认值跟随主题。|
1562| fontColor                    | [ResourceColor](ts-types.md#resourcecolor)  | 否    | 设置placeholder文本颜色。<br/>默认值跟随主题。|
1563
1564## RichEditorImageSpanOptions
1565
1566添加图片的偏移位置和图片样式信息。
1567
1568**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1569
1570| 名称                    | 类型                                       | 必填   | 说明                         |
1571| --------------------- | ---------------------------------------- | ---- | -------------------------- |
1572| offset                | number                                   | 否    | 添加图片的位置。省略时,添加到所有内容的最后。<br/>当值小于0时,放在所有内容最前面;当值大于所有内容长度时,放在所有内容最后面。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1573| imageStyle            | [RichEditorImageSpanStyle](#richeditorimagespanstyle) | 否    | 图片样式信息。省略时,使用系统默认图片信息。     <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1574| gesture<sup>11+</sup> | [RichEditorGesture](#richeditorgesture11) | 否    | 行为触发回调。省略时,仅使用系统默认行为。      <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
1575
1576## RichEditorImageSpanStyle
1577
1578图片样式。
1579
1580**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1581
1582| 名称                        | 类型                                       | 必填   | 说明                                       |
1583| ------------------------- | ---------------------------------------- | ---- | ---------------------------------------- |
1584| size                      | [[Dimension](ts-types.md#dimension10), [Dimension](ts-types.md#dimension10)] | 否    | 图片宽度和高度。默认值:size的默认值与objectFit的值有关,不同的objectFit值对应的size默认值也不同。objectFit的值为Cover时,图片高度为组件高度减去组件上下内边距,图片宽度为组件宽度减去组件左右内边距。不支持以Percentage形式设置。  <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。                               |
1585| verticalAlign             | [ImageSpanAlignment](ts-basic-components-imagespan.md#imagespanalignment) | 否    | 图片垂直对齐方式。<br/>默认值:ImageSpanAlignment.BOTTOM <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。|
1586| objectFit                 | [ImageFit](ts-appendix-enums.md#imagefit) | 否    | 图片缩放类型。<br/> 默认值:ImageFit.Cover。  <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。       |
1587| layoutStyle<sup>11+</sup> | [RichEditorLayoutStyle](#richeditorlayoutstyle11) | 否    | 图片布局风格。默认值:{"borderRadius":"","margin":""}<br/>   <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。                          |
1588
1589## RichEditorSymbolSpanOptions<sup>11+</sup>
1590
1591添加SymbolSpan组件的偏移位置和SymbolSpan组件样式信息。
1592
1593**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1594
1595**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1596
1597| 名称     | 类型                                       | 必填   | 说明                         |
1598| ------ | ---------------------------------------- | ---- | -------------------------- |
1599| offset | number                                   | 否    | 添加组件的位置。省略时,添加到所有内容的最后。<br/>当值小于0时,放在所有内容最前面;当值大于所有内容长度时,放在所有内容最后面。 |
1600| style  | [RichEditorSymbolSpanStyle](#richeditorsymbolspanstyle11) | 否    | 组件样式信息。省略时,使用系统默认样式信息。     |
1601
1602## RichEditorSymbolSpanStyle<sup>11+</sup>
1603
1604组件SymbolSpan样式信息。
1605
1606**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1607
1608**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1609
1610| 名称 | 类型 | 必填 | 说明                               |
1611| ------ | -------- | ---- | -------------------------------------- |
1612| fontColor | Array\<[ResourceColor](ts-types.md#resourcecolor)\> | 否 | 设置SymbolSpan组件颜色。<br/> 默认值:不同渲染策略下默认值不同。 |
1613| fontSize | number \| string \| [Resource](ts-types.md#resource) | 否 | 设置SymbolSpan组件大小,默认单位为fp。<br/>默认值:跟随主题。 |
1614| fontWeight | number \| [FontWeight](ts-appendix-enums.md#fontweight) \| string | 否 | 设置SymbolSpan组件粗细。<br/>number类型取值[100,900],取值间隔为100,默认为400,取值越大,字体越粗。<br/>string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular” 、“medium”分别对应FontWeight中相应的枚举值。<br/>默认值:FontWeight.Normal。 |
1615| renderingStrategy | [SymbolRenderingStrategy](ts-basic-components-symbolGlyph.md#symbolrenderingstrategy11枚举说明)	| 否 | 设置SymbolSpan组件渲染策略。<br/>默认值:SymbolRenderingStrategy.SINGLE。 |
1616| effectStrategy | [SymbolEffectStrategy](ts-basic-components-symbolGlyph.md#symboleffectstrategy11枚举说明)	| 否 | 设置SymbolSpan组件动效策略。<br/>默认值:SymbolEffectStrategy.NONE。 |
1617
1618## RichEditorBuilderSpanOptions<sup>11+</sup>
1619
1620添加图片的偏移位置和图片样式信息。
1621
1622**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1623
1624**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1625
1626| 名称     | 类型     | 必填   | 说明                                    |
1627| ------ | ------ | ---- | ------------------------------------- |
1628| offset | number | 否    | 添加builder的位置。省略或者为异常值时,添加到所有内容的最后。 |
1629
1630## RichEditorSpan<sup>12+</sup>
1631
1632type RichEditorSpan = RichEditorImageSpanResult | RichEditorTextSpanResult
1633
1634RichEditor span信息。
1635
1636**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1637
1638**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1639
1640| 类型   | 说明       |
1641| ------ | ---------- |
1642| [RichEditorImageSpanResult](#richeditorimagespanresult) | 后端返回的图片信息。 |
1643| [RichEditorTextSpanResult](#richeditortextspanresult) | 后端返回的文本样式信息。 |
1644
1645## SelectionMenuOptions<sup>10+</sup>
1646
1647菜单的选项。
1648
1649**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1650
1651| 名称          | 类型         | 必填   | 说明            |
1652| ----------- | ---------- | ---- | ------------- |
1653| onAppear    | [MenuOnAppearCallback](#menuonappearcallback12) | 否    | 自定义选择菜单弹出时回调。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
1654| onDisappear | Callback\<void\>  | 否    | 自定义选择菜单关闭时回调。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
1655| menuType<sup>13+</sup> | [MenuType](ts-text-common.md#menutype13枚举说明) | 否 | 自定义选择菜单类型。<br/>**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。 |
1656
1657## PasteEvent<sup>11+</sup>
1658
1659定义用户粘贴事件。
1660
1661**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
1662
1663**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1664
1665| 名称             | 类型          | 必填   | 说明                            |
1666| -------------- | ----------- | ---- | ----------------------------- |
1667| preventDefault | Callback\<void\> | 否    | 阻止系统默认粘贴事件。 |
1668
1669## CutEvent<sup>12+</sup>
1670
1671定义用户剪切事件。
1672
1673**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1674
1675**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1676
1677| 名称             | 类型          | 必填   | 说明                            |
1678| -------------- | ----------- | ---- | ----------------------------- |
1679| preventDefault | Callback\<void\>  | 否    | 阻止系统默认剪切事件。 |
1680
1681## CopyEvent<sup>12+</sup>
1682
1683定义用户拷贝事件。
1684
1685**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1686
1687**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1688
1689| 名称             | 类型          | 必填   | 说明                            |
1690| -------------- | ----------- | ---- | ----------------------------- |
1691| preventDefault | Callback\<void\>  | 否    | 阻止系统默认拷贝事件。 |
1692
1693## RichEditorGesture<sup>11+</sup>
1694
1695用户行为回调。
1696
1697**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1698
1699**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1700
1701| 名称          | 类型         | 必填   | 说明            |
1702| ----------- | ---------- | ---- | ------------- |
1703| onClick    | Callback\<[ClickEvent](ts-universal-events-click.md#clickevent对象说明)\> | 否    | [ClickEvent](ts-universal-events-click.md#clickevent对象说明)为用户点击事件。<br/>点击完成时回调事件。<br/>双击时,第一次点击触发回调事件。|
1704| onLongPress | Callback\<[GestureEvent](ts-gesture-settings.md#gestureevent对象说明)\>  | 否    | [GestureEvent](ts-gesture-settings.md#gestureevent对象说明)为用户长按事件。<br/>长按完成时回调事件。 |
1705
1706## KeyboardOptions<sup>12+</sup>
1707
1708设置自定义键盘是否支持避让功能。
1709
1710**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1711
1712**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1713
1714| 名称            | 类型              | 必填   | 说明                               |
1715| --------------- | ---------------  |---- | ------------------------------------  |
1716| supportAvoidance |  boolean      | 否 | 设置自定义键盘是否支持避让功能;默认值为false不支持避让,true为支持避让。 |
1717
1718## SubmitCallback<sup>12+</sup>
1719
1720type SubmitCallback = (enterKey: EnterKeyType, event: SubmitEvent) => void
1721
1722软键盘按下回车键时的回调事件。
1723
1724**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1725
1726**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1727
1728**参数:**
1729
1730| 参数名   | 类型                                                         | 必填 | 说明                                                     |
1731| -------- | ------------------------------------------------------------ | ---- | -------------------------------------------------------- |
1732| enterKey | [EnterKeyType](ts-types.md#enterkeytype枚举说明)             | 是   | 软键盘输入法回车键类型。具体类型见EnterKeyType枚举说明。 |
1733| event    | [SubmitEvent](ts-basic-components-textinput.md#submitevent11对象说明) | 是   | 当提交的时候,提供保持RichEditor编辑状态的方法。         |
1734
1735## MenuOnAppearCallback<sup>12+</sup>
1736
1737type MenuOnAppearCallback = (start: number, end: number) => void
1738
1739自定义选择菜单弹出时触发的回调事件。
1740
1741**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1742
1743**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1744
1745**参数:**
1746
1747| 参数名  | 类型                                             | 必填 | 说明                                                     |
1748| -------- | ------------------------------------------------ | ---- | -------------------------------------------------------- |
1749| start | number | 是   | 选中内容的起始位置。 |
1750| end    | number         | 是   | 选中内容的终止位置。         |
1751
1752## PasteEventCallback<sup>12+</sup>
1753
1754type PasteEventCallback = (event?: PasteEvent) => void
1755
1756完成粘贴前,触发回调。
1757
1758**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
1759
1760type PasteEventCallback = (event?: PasteEvent) => void
1761
1762**系统能力:** SystemCapability.ArkUI.ArkUI.Full
1763
1764**参数:**
1765
1766| 参数名     | 类型                                             | 必填 | 说明                                                     |
1767| -------- | ------------------------------------------------ | ---- | -------------------------------------------------------- |
1768| event  | [PasteEvent](#pasteevent11) | 否   | 定义用户粘贴事件。 |
1769
1770## 示例
1771
1772### 示例1
1773
1774```ts
1775// xxx.ets
1776@Entry
1777@Component
1778struct Index {
1779  controller: RichEditorController = new RichEditorController();
1780  options: RichEditorOptions = { controller: this.controller };
1781  private start: number = -1;
1782  private end: number = -1;
1783  @State message: string = "[-1, -1]"
1784  @State content: string = ""
1785
1786  build() {
1787    Column() {
1788      Column() {
1789        Text("selection range:").width("100%")
1790        Text() {
1791          Span(this.message)
1792        }.width("100%")
1793        Text("selection content:").width("100%")
1794        Text() {
1795          Span(this.content)
1796        }.width("100%")
1797      }
1798      .borderWidth(1)
1799      .borderColor(Color.Red)
1800      .width("100%")
1801      .height("20%")
1802
1803      Row() {
1804        Button("更新样式:加粗").onClick(() => {
1805          this.controller.updateSpanStyle({
1806            start: this.start,
1807            end: this.end,
1808            textStyle:
1809            {
1810              fontWeight: FontWeight.Bolder
1811            }
1812          })
1813        })
1814        Button("获取选择内容").onClick(() => {
1815          this.content = "";
1816          this.controller.getSpans({
1817            start: this.start,
1818            end: this.end
1819          }).forEach(item => {
1820            if(typeof(item as RichEditorImageSpanResult)['imageStyle'] != 'undefined'){
1821              this.content += (item as RichEditorImageSpanResult).valueResourceStr;
1822              this.content += "\n"
1823            } else {
1824              if(typeof(item as RichEditorTextSpanResult)['symbolSpanStyle'] != 'undefined') {
1825                this.content += (item as RichEditorTextSpanResult).symbolSpanStyle?.fontSize;
1826                this.content += "\n"
1827              }else {
1828                this.content += (item as RichEditorTextSpanResult).value;
1829                this.content += "\n"
1830              }
1831            }
1832          })
1833        })
1834        Button("删除选择内容").onClick(() => {
1835          this.controller.deleteSpans({
1836            start: this.start,
1837            end: this.end
1838          })
1839          this.start = -1;
1840          this.end = -1;
1841          this.message = "[" + this.start + ", " + this.end + "]"
1842        })
1843      }
1844      .borderWidth(1)
1845      .borderColor(Color.Red)
1846      .width("100%")
1847      .height("10%")
1848
1849      Column() {
1850        RichEditor(this.options)
1851          .onReady(() => {
1852            this.controller.addTextSpan("012345",
1853              {
1854                style:
1855                {
1856                  fontColor: Color.Orange,
1857                  fontSize: 30
1858                }
1859              })
1860            this.controller.addSymbolSpan($r("sys.symbol.ohos_trash"),
1861              {
1862                style:
1863                {
1864                  fontSize: 30
1865                }
1866              })
1867            this.controller.addImageSpan($r("app.media.icon"),
1868              {
1869                imageStyle:
1870                {
1871                  size: ["57px", "57px"]
1872                }
1873              })
1874            this.controller.addTextSpan("56789",
1875              {
1876                style:
1877                {
1878                  fontColor: Color.Black,
1879                  fontSize: 30
1880                }
1881              })
1882          })
1883          .onSelect((value: RichEditorSelection) => {
1884            this.start = value.selection[0];
1885            this.end = value.selection[1];
1886            this.message = "[" + this.start + ", " + this.end + "]"
1887          })
1888          .aboutToIMEInput((value: RichEditorInsertValue) => {
1889            console.log("---------------------- aboutToIMEInput ----------------------")
1890            console.log("insertOffset:" + value.insertOffset)
1891            console.log("insertValue:" + value.insertValue)
1892            return true;
1893          })
1894          .onIMEInputComplete((value: RichEditorTextSpanResult) => {
1895            console.log("---------------------- onIMEInputComplete ---------------------")
1896            console.log("spanIndex:" + value.spanPosition.spanIndex)
1897            console.log("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]")
1898            console.log("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]")
1899            console.log("value:" + value.value)
1900          })
1901          .aboutToDelete((value: RichEditorDeleteValue) => {
1902            console.log("---------------------- aboutToDelete --------------------------")
1903            console.log("offset:" + value.offset)
1904            console.log("direction:" + value.direction)
1905            console.log("length:" + value.length)
1906            value.richEditorDeleteSpans.forEach(item => {
1907              console.log("---------------------- item --------------------------")
1908              console.log("spanIndex:" + item.spanPosition.spanIndex)
1909              console.log("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]")
1910              console.log("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]")
1911              if (typeof(item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') {
1912                console.log("image:" + (item as RichEditorImageSpanResult).valueResourceStr)
1913              } else {
1914                console.log("text:" + (item as RichEditorTextSpanResult).value)
1915              }
1916            })
1917            return true;
1918          })
1919          .onDeleteComplete(() => {
1920            console.log("---------------------- onDeleteComplete ------------------------")
1921          })
1922          .placeholder("input...", {
1923            fontColor: Color.Gray,
1924            font: {
1925              size: 16,
1926              weight: FontWeight.Normal,
1927              family: "HarmonyOS Sans",
1928              style: FontStyle.Normal
1929            }
1930          })
1931          .borderWidth(1)
1932          .borderColor(Color.Green)
1933          .width("100%")
1934          .height("30%")
1935      }
1936      .borderWidth(1)
1937      .borderColor(Color.Red)
1938      .width("100%")
1939      .height("70%")
1940    }
1941  }
1942}
1943```
1944![richeditor](figures/richeditor.gif)
1945
1946### 示例2
1947
1948```ts
1949// xxx.ets
1950@Entry
1951@Component
1952struct RichEditorExample {
1953  controller: RichEditorController = new RichEditorController()
1954
1955  // 自定义键盘组件
1956  @Builder CustomKeyboardBuilder() {
1957    Column() {
1958      Grid() {
1959        ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '#'], (item: number | string) => {
1960          GridItem() {
1961            Button(item + "")
1962              .width(110).onClick(() => {
1963              this.controller.addTextSpan(item + '', {
1964                offset: this.controller.getCaretOffset(),
1965                style:
1966                {
1967                  fontColor: Color.Orange,
1968                  fontSize: 30
1969                }
1970              })
1971              this.controller.setCaretOffset(this.controller.getCaretOffset() + item.toString().length)
1972            })
1973          }
1974        })
1975      }.maxCount(3).columnsGap(10).rowsGap(10).padding(5)
1976    }.backgroundColor(Color.Gray)
1977  }
1978
1979  build() {
1980    Column() {
1981      RichEditor({ controller: this.controller })
1982        // 绑定自定义键盘
1983        .customKeyboard(this.CustomKeyboardBuilder()).margin(10).border({ width: 1 })
1984        .height(200)
1985        .borderWidth(1)
1986        .borderColor(Color.Red)
1987        .width("100%")
1988    }
1989  }
1990}
1991```
1992
1993![customKeyboard](figures/richEditorCustomKeyboard.gif)
1994
1995### 示例3
1996
1997```ts
1998// xxx.ets
1999import { BusinessError, pasteboard } from '@kit.BasicServicesKit';
2000
2001export interface SelectionMenuTheme {
2002  imageSize: number;
2003  buttonSize: number;
2004  menuSpacing: number;
2005  editorOptionMargin: number;
2006  expandedOptionPadding: number;
2007  defaultMenuWidth: number;
2008  imageFillColor: Resource;
2009  backGroundColor: Resource;
2010  iconBorderRadius: Resource;
2011  containerBorderRadius: Resource;
2012  cutIcon: Resource;
2013  copyIcon: Resource;
2014  pasteIcon: Resource;
2015  selectAllIcon: Resource;
2016  shareIcon: Resource;
2017  translateIcon: Resource;
2018  searchIcon: Resource;
2019  arrowDownIcon: Resource;
2020  iconPanelShadowStyle: ShadowStyle;
2021  iconFocusBorderColor: Resource;
2022}
2023
2024export const defaultTheme: SelectionMenuTheme = {
2025  imageSize: 24,
2026  buttonSize: 48,
2027  menuSpacing: 8,
2028  editorOptionMargin: 1,
2029  expandedOptionPadding: 3,
2030  defaultMenuWidth: 256,
2031  imageFillColor: $r('sys.color.ohos_id_color_primary'),
2032  backGroundColor: $r('sys.color.ohos_id_color_dialog_bg'),
2033  iconBorderRadius: $r('sys.float.ohos_id_corner_radius_default_m'),
2034  containerBorderRadius: $r('sys.float.ohos_id_corner_radius_card'),
2035  cutIcon: $r("sys.media.ohos_ic_public_cut"),
2036  copyIcon: $r("sys.media.ohos_ic_public_copy"),
2037  pasteIcon: $r("sys.media.ohos_ic_public_paste"),
2038  selectAllIcon: $r("sys.media.ohos_ic_public_select_all"),
2039  shareIcon: $r("sys.media.ohos_ic_public_share"),
2040  translateIcon: $r("sys.media.ohos_ic_public_translate_c2e"),
2041  searchIcon: $r("sys.media.ohos_ic_public_search_filled"),
2042  arrowDownIcon: $r("sys.media.ohos_ic_public_arrow_down"),
2043  iconPanelShadowStyle: ShadowStyle.OUTER_DEFAULT_MD,
2044  iconFocusBorderColor: $r('sys.color.ohos_id_color_focused_outline'),
2045}
2046
2047@Entry
2048@Component
2049struct SelectionMenu {
2050  @State message: string = 'Hello World'
2051  @State textSize: number = 40
2052  @State sliderShow: boolean = false
2053  @State start: number = -1
2054  @State end: number = -1
2055  @State colorTransparent: Color = Color.Transparent
2056  controller: RichEditorController = new RichEditorController();
2057  options: RichEditorOptions = { controller: this.controller }
2058  private iconArr: Array<Resource> =
2059    [$r('app.media.icon'), $r("app.media.icon"), $r('app.media.icon'),
2060    $r("app.media.icon"), $r('app.media.icon')]
2061  @State iconBgColor: ResourceColor[] = new Array(this.iconArr.length).fill(this.colorTransparent)
2062  @State pasteEnable: boolean = false
2063  @State visibilityValue: Visibility = Visibility.Visible
2064  @State textStyle: RichEditorTextStyle = {}
2065  private fontWeightTable: string[] = ["100", "200", "300", "400", "500", "600", "700", "800", "900", "bold", "normal", "bolder", "lighter", "medium", "regular"]
2066  private theme: SelectionMenuTheme = defaultTheme;
2067
2068  aboutToAppear() {
2069    if (this.controller) {
2070      let richEditorSelection = this.controller.getSelection()
2071      if (richEditorSelection) {
2072        let start = richEditorSelection.selection[0]
2073        let end = richEditorSelection.selection[1]
2074        if (start === 0 && this.controller.getSpans({ start: end + 1, end: end + 1 }).length === 0) {
2075          this.visibilityValue = Visibility.None
2076        } else {
2077          this.visibilityValue = Visibility.Visible
2078        }
2079      }
2080    }
2081    let sysBoard = pasteboard.getSystemPasteboard()
2082    if (sysBoard && sysBoard.hasDataSync()) {
2083      this.pasteEnable = true
2084    } else {
2085      this.pasteEnable = false
2086    }
2087  }
2088
2089  build() {
2090    Column() {
2091      Column() {
2092        RichEditor(this.options)
2093          .onReady(() => {
2094            this.controller.addTextSpan(this.message, { style: { fontColor: Color.Orange, fontSize: 30 } })
2095          })
2096          .onSelect((value: RichEditorSelection) => {
2097            if (value.selection[0] == -1 && value.selection[1] == -1) {
2098              return
2099            }
2100            this.start = value.selection[0]
2101            this.end = value.selection[1]
2102          })
2103          .bindSelectionMenu(RichEditorSpanType.TEXT, this.panel, ResponseType.LongPress, { onDisappear: () => {
2104            this.sliderShow = false
2105          }})
2106          .bindSelectionMenu(RichEditorSpanType.TEXT, this.panel, ResponseType.RightClick, { onDisappear: () => {
2107            this.sliderShow = false
2108          }})
2109          .borderWidth(1)
2110          .borderColor(Color.Red)
2111          .width(200)
2112          .height(200)
2113      }.width('100%').backgroundColor(Color.White)
2114    }.height('100%')
2115  }
2116
2117  PushDataToPasteboard(richEditorSelection: RichEditorSelection) {
2118    let sysBoard = pasteboard.getSystemPasteboard()
2119    let pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, '')
2120    if (richEditorSelection.spans && richEditorSelection.spans.length > 0) {
2121      let count = richEditorSelection.spans.length
2122      for (let i = count - 1; i >= 0; i--) {
2123        let item = richEditorSelection.spans[i]
2124        if ((item as RichEditorTextSpanResult)?.textStyle) {
2125          let span = item as RichEditorTextSpanResult
2126          let style = span.textStyle
2127          let data = pasteboard.createRecord(pasteboard.MIMETYPE_TEXT_PLAIN, span.value.substring(span.offsetInSpan[0], span.offsetInSpan[1]))
2128          let prop = pasteData.getProperty()
2129          let temp: Record<string, Object> = {
2130            'color': style.fontColor,
2131            'size': style.fontSize,
2132            'style': style.fontStyle,
2133            'weight': this.fontWeightTable[style.fontWeight],
2134            'fontFamily': style.fontFamily,
2135            'decorationType': style.decoration.type,
2136            'decorationColor': style.decoration.color
2137          }
2138          prop.additions[i] = temp;
2139          pasteData.addRecord(data)
2140          pasteData.setProperty(prop)
2141        }
2142      }
2143    }
2144    sysBoard.clearData()
2145    sysBoard.setData(pasteData).then(() => {
2146      console.info('SelectionMenu copy option, Succeeded in setting PasteData.');
2147      this.pasteEnable = true;
2148    }).catch((err: BusinessError) => {
2149      console.error('SelectionMenu copy option, Failed to set PasteData. Cause:' + err.message);
2150    })
2151  }
2152
2153  PopDataFromPasteboard(richEditorSelection: RichEditorSelection) {
2154    let start = richEditorSelection.selection[0]
2155    let end = richEditorSelection.selection[1]
2156    if (start == end && this.controller) {
2157      start = this.controller.getCaretOffset()
2158      end = this.controller.getCaretOffset()
2159    }
2160    let moveOffset = 0
2161    let sysBoard = pasteboard.getSystemPasteboard()
2162    sysBoard.getData((err, data) => {
2163      if (err) {
2164        return
2165      }
2166      let count = data.getRecordCount()
2167      for (let i = 0; i < count; i++) {
2168        const element = data.getRecord(i);
2169        let tex: RichEditorTextStyle = {
2170          fontSize: 16,
2171          fontColor: Color.Black,
2172          fontWeight: FontWeight.Normal,
2173          fontFamily: "HarmonyOS Sans",
2174          fontStyle: FontStyle.Normal,
2175          decoration: { type: TextDecorationType.None, color: "#FF000000", style: TextDecorationStyle.SOLID }
2176        }
2177        if (data.getProperty() && data.getProperty().additions[i]) {
2178          const tmp = data.getProperty().additions[i] as Record<string, Object | undefined>;
2179          if (tmp.color) {
2180            tex.fontColor = tmp.color as ResourceColor;
2181          }
2182          if (tmp.size) {
2183            tex.fontSize = tmp.size as Length | number;
2184          }
2185          if (tmp.style) {
2186            tex.fontStyle = tmp.style as FontStyle;
2187          }
2188          if (tmp.weight) {
2189            tex.fontWeight = tmp.weight as number | FontWeight | string;
2190          }
2191          if (tmp.fontFamily) {
2192            tex.fontFamily = tmp.fontFamily as ResourceStr;
2193          }
2194          if (tmp.decorationType && tex.decoration) {
2195            tex.decoration.type = tmp.decorationType as TextDecorationType;
2196          }
2197          if (tmp.decorationColor && tex.decoration) {
2198            tex.decoration.color = tmp.decorationColor as ResourceColor;
2199          }
2200          if (tex.decoration) {
2201            tex.decoration = { type: tex.decoration.type, color: tex.decoration.color }
2202          }
2203        }
2204        if (element && element.plainText && element.mimeType === pasteboard.MIMETYPE_TEXT_PLAIN && this.controller) {
2205          this.controller.addTextSpan(element.plainText,
2206            {
2207              style: tex,
2208              offset: start + moveOffset
2209            }
2210          )
2211          moveOffset += element.plainText.length
2212        }
2213      }
2214      if (this.controller) {
2215        this.controller.setCaretOffset(start + moveOffset)
2216        this.controller.closeSelectionMenu()
2217      }
2218      if (start != end && this.controller) {
2219        this.controller.deleteSpans({ start: start + moveOffset, end: end + moveOffset })
2220      }
2221    })
2222  }
2223
2224  @Builder
2225  panel() {
2226    Column() {
2227      this.iconPanel()
2228      if (!this.sliderShow) {
2229        this.SystemMenu()
2230      } else {
2231        this.sliderPanel()
2232      }
2233    }.width(256)
2234  }
2235
2236  @Builder iconPanel() {
2237    Column() {
2238      Row({ space: 2 }) {
2239        ForEach(this.iconArr, (item:Resource, index ?: number) => {
2240          Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
2241            Image(item).fillColor(this.theme.imageFillColor).width(24).height(24).focusable(true).draggable(false)
2242          }
2243          .borderRadius(this.theme.iconBorderRadius)
2244          .width(this.theme.buttonSize)
2245          .height(this.theme.buttonSize)
2246          .onClick(() => {
2247            if (index as number == 0) {
2248              this.sliderShow = false
2249              if (this.controller) {
2250                let selection = this.controller.getSelection();
2251                let spans = selection.spans
2252                spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => {
2253                  if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') {
2254                    let span = item as RichEditorTextSpanResult
2255                    this.textStyle = span.textStyle
2256                    let start = span.offsetInSpan[0]
2257                    let end = span.offsetInSpan[1]
2258                    let offset = span.spanPosition.spanRange[0]
2259                    if (this.textStyle.fontWeight != 11) {
2260                      this.textStyle.fontWeight = FontWeight.Bolder
2261                    } else {
2262                      this.textStyle.fontWeight = FontWeight.Normal
2263                    }
2264                    this.controller.updateSpanStyle({
2265                      start: offset + start,
2266                      end: offset + end,
2267                      textStyle: this.textStyle
2268                    })
2269                  }
2270                })
2271              }
2272            } else if (index as number == 1) {
2273              this.sliderShow = false
2274              if (this.controller) {
2275                let selection = this.controller.getSelection();
2276                let spans = selection.spans
2277                spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => {
2278                  if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') {
2279                    let span = item as RichEditorTextSpanResult
2280                    this.textStyle = span.textStyle
2281                    let start = span.offsetInSpan[0]
2282                    let end = span.offsetInSpan[1]
2283                    let offset = span.spanPosition.spanRange[0]
2284                    if (this.textStyle.fontStyle == FontStyle.Italic) {
2285                      this.textStyle.fontStyle = FontStyle.Normal
2286                    } else {
2287                      this.textStyle.fontStyle = FontStyle.Italic
2288                    }
2289                    this.controller.updateSpanStyle({
2290                      start: offset + start,
2291                      end: offset + end,
2292                      textStyle: this.textStyle
2293                    })
2294                  }
2295                })
2296              }
2297            } else if (index as number == 2) {
2298              this.sliderShow = false
2299              if (this.controller) {
2300                let selection = this.controller.getSelection();
2301                let spans = selection.spans
2302                spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => {
2303                  if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') {
2304                    let span = item as RichEditorTextSpanResult
2305                    this.textStyle = span.textStyle
2306                    let start = span.offsetInSpan[0]
2307                    let end = span.offsetInSpan[1]
2308                    let offset = span.spanPosition.spanRange[0]
2309                    if (this.textStyle.decoration) {
2310                      if (this.textStyle.decoration.type == TextDecorationType.Underline) {
2311                        this.textStyle.decoration.type = TextDecorationType.None
2312                      } else {
2313                        this.textStyle.decoration.type = TextDecorationType.Underline
2314                      }
2315                    } else {
2316                      this.textStyle.decoration = { type: TextDecorationType.Underline, color: Color.Black, style: TextDecorationStyle.SOLID }
2317                    }
2318                    this.controller.updateSpanStyle({
2319                      start: offset + start,
2320                      end: offset + end,
2321                      textStyle: this.textStyle
2322                    })
2323                  }
2324                })
2325              }
2326            } else if (index as number == 3) {
2327              this.sliderShow = !this.sliderShow
2328            } else if (index as number == 4) {
2329              this.sliderShow = false
2330              if (this.controller) {
2331                let selection = this.controller.getSelection();
2332                let spans = selection.spans
2333                spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => {
2334                  if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') {
2335                    let span = item as RichEditorTextSpanResult
2336                    this.textStyle = span.textStyle
2337                    let start = span.offsetInSpan[0]
2338                    let end = span.offsetInSpan[1]
2339                    let offset = span.spanPosition.spanRange[0]
2340                    if (this.textStyle.fontColor == Color.Orange || this.textStyle.fontColor == '#FFFFA500') {
2341                      this.textStyle.fontColor = Color.Black
2342                    } else {
2343                      this.textStyle.fontColor = Color.Orange
2344                    }
2345                    this.controller.updateSpanStyle({
2346                      start: offset + start,
2347                      end: offset + end,
2348                      textStyle: this.textStyle
2349                    })
2350                  }
2351                })
2352              }
2353            }
2354          })
2355          .onTouch((event?: TouchEvent | undefined) => {
2356            if(event != undefined){
2357              if (event.type === TouchType.Down) {
2358                this.iconBgColor[index as number] = $r('sys.color.ohos_id_color_click_effect')
2359              }
2360              if (event.type === TouchType.Up) {
2361                this.iconBgColor[index as number] = this.colorTransparent
2362              }
2363            }
2364          })
2365          .onHover((isHover?: boolean, event?: HoverEvent) => {
2366            this.iconBgColor.forEach((icon:ResourceColor, index1) => {
2367              this.iconBgColor[index1] = this.colorTransparent
2368            })
2369            if(isHover != undefined) {
2370              this.iconBgColor[index as number] = $r('sys.color.ohos_id_color_hover')
2371            }
2372          })
2373          .backgroundColor(this.iconBgColor[index as number])
2374        })
2375      }
2376    }
2377    .clip(true)
2378    .width(this.theme.defaultMenuWidth)
2379    .padding(this.theme.expandedOptionPadding)
2380    .borderRadius(this.theme.containerBorderRadius)
2381    .margin({ bottom: this.theme.menuSpacing })
2382    .backgroundColor(this.theme.backGroundColor)
2383    .shadow(this.theme.iconPanelShadowStyle)
2384  }
2385
2386  @Builder
2387  SystemMenu() {
2388    Column() {
2389      Menu() {
2390        if (this.controller) {
2391          MenuItemGroup() {
2392            MenuItem({ startIcon: this.theme.cutIcon, content: "剪切", labelInfo: "Ctrl+X" })
2393              .onClick(() => {
2394                if (!this.controller) {
2395                  return
2396                }
2397                let richEditorSelection = this.controller.getSelection()
2398                this.PushDataToPasteboard(richEditorSelection);
2399                this.controller.deleteSpans({
2400                  start: richEditorSelection.selection[0],
2401                  end: richEditorSelection.selection[1]
2402                })
2403              })
2404            MenuItem({ startIcon: this.theme.copyIcon, content: "复制", labelInfo: "Ctrl+C" })
2405              .onClick(() => {
2406                if (!this.controller) {
2407                  return
2408                }
2409                let richEditorSelection = this.controller.getSelection()
2410                this.PushDataToPasteboard(richEditorSelection);
2411                this.controller.closeSelectionMenu()
2412              })
2413            MenuItem({ startIcon: this.theme.pasteIcon, content: "粘贴", labelInfo: "Ctrl+V" })
2414              .enabled(this.pasteEnable)
2415              .onClick(() => {
2416                if (!this.controller) {
2417                  return
2418                }
2419                let richEditorSelection = this.controller.getSelection()
2420                this.PopDataFromPasteboard(richEditorSelection)
2421              })
2422            MenuItem({ startIcon: this.theme.selectAllIcon, content: "全选", labelInfo: "Ctrl+A" })
2423              .visibility(this.visibilityValue)
2424              .onClick(() => {
2425                if (!this.controller) {
2426                  return
2427                }
2428                this.controller.setSelection(-1, -1)
2429                this.visibilityValue = Visibility.None
2430              })
2431            MenuItem({ startIcon: this.theme.shareIcon, content: "分享", labelInfo: "" })
2432              .enabled(false)
2433            MenuItem({ startIcon: this.theme.translateIcon, content: "翻译", labelInfo: "" })
2434              .enabled(false)
2435            MenuItem({ startIcon: this.theme.searchIcon, content: "搜索", labelInfo: "" })
2436              .enabled(false)
2437          }
2438        }
2439      }
2440      .onVisibleAreaChange([0.0, 1.0], () => {
2441        if (!this.controller) {
2442          return
2443        }
2444        let richEditorSelection = this.controller.getSelection()
2445        let start = richEditorSelection.selection[0]
2446        let end = richEditorSelection.selection[1]
2447        if (start === 0 && this.controller.getSpans({ start: end + 1, end: end + 1 }).length === 0) {
2448          this.visibilityValue = Visibility.None
2449        } else {
2450          this.visibilityValue = Visibility.Visible
2451        }
2452      })
2453      .radius(this.theme.containerBorderRadius)
2454      .clip(true)
2455      .backgroundColor(Color.White)
2456      .width(this.theme.defaultMenuWidth)
2457    }
2458    .width(this.theme.defaultMenuWidth)
2459  }
2460
2461  @Builder sliderPanel() {
2462    Column() {
2463      Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
2464        Text('A').fontSize(15)
2465        Slider({ value: this.textSize, step: 10, style: SliderStyle.InSet })
2466          .width(210)
2467          .onChange((value: number, mode: SliderChangeMode) => {
2468            if (this.controller) {
2469              let selection = this.controller.getSelection();
2470              if (mode == SliderChangeMode.End) {
2471                if (this.textSize == undefined) {
2472                  this.textSize = 0
2473                }
2474                let spans = selection.spans
2475                spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => {
2476                  if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') {
2477                    this.textSize = Math.max(this.textSize, (item as RichEditorTextSpanResult).textStyle.fontSize)
2478                  }
2479                })
2480              }
2481              if (mode == SliderChangeMode.Moving || mode == SliderChangeMode.Click) {
2482                this.start = selection.selection[0]
2483                this.end = selection.selection[1]
2484                this.textSize = value
2485                this.controller.updateSpanStyle({
2486                  start: this.start,
2487                  end: this.end,
2488                  textStyle: { fontSize: this.textSize }
2489                })
2490              }
2491            }
2492          })
2493        Text('A').fontSize(20).fontWeight(FontWeight.Medium)
2494      }.borderRadius(this.theme.containerBorderRadius)
2495    }
2496    .shadow(ShadowStyle.OUTER_DEFAULT_MD)
2497    .backgroundColor(Color.White)
2498    .borderRadius(this.theme.containerBorderRadius)
2499    .padding(15)
2500    .height(48)
2501  }
2502}
2503```
2504> **说明:**
2505>
2506> 系统暂未预置加粗、斜体等图标,示例代码使用系统默认图标,开发者使用时需自行替换iconArr中的资源。
2507
2508![selectionMenu](figures/richEditorSelectionMenu.png)
2509
2510### 示例4
2511
2512```ts
2513// xxx.ets
2514@Entry
2515@Component
2516struct Index {
2517  controller: RichEditorController = new RichEditorController();
2518  options: RichEditorOptions = { controller: this.controller };
2519  private start: number = -1;
2520  private end: number = -1;
2521  @State message: string = "[-1, -1]"
2522  @State content: string = ""
2523  @State paddingVal: number = 5
2524  @State borderRad: number = 4
2525
2526  build() {
2527    Column() {
2528      Column() {
2529        Text("selection range:").width("100%")
2530        Text() {
2531          Span(this.message)
2532        }.width("100%")
2533        Text("selection content:").width("100%")
2534        Text() {
2535          Span(this.content)
2536        }.width("100%")
2537      }
2538      .borderWidth(1)
2539      .borderColor(Color.Red)
2540      .width("100%")
2541      .height("20%")
2542
2543      Row() {
2544        Button("updateSpanStyle1")
2545          .fontSize(12)
2546          .onClick(() => {
2547            this.controller.updateSpanStyle({
2548              start: this.start,
2549              textStyle:
2550              {
2551                fontWeight: FontWeight.Bolder
2552              },
2553              imageStyle: {
2554                size: ["80px", "80px"],
2555                layoutStyle: {
2556                  borderRadius: undefined,
2557                  margin: undefined
2558                }
2559              }
2560            })
2561          })
2562
2563        Button("updateSpanStyle2")
2564          .fontSize(12)
2565          .onClick(() => {
2566            this.controller.updateSpanStyle({
2567              start: this.start,
2568              textStyle:
2569              {
2570                fontWeight: FontWeight.Bolder
2571              },
2572              imageStyle: {
2573                size: ["70px", "70px"],
2574                layoutStyle: {
2575                  borderRadius: { topLeft: '100px', topRight: '20px', bottomLeft: '100px', bottomRight: '20px' },
2576                  margin: { left: '30px', top: '20px', right: '20px', bottom: '20px' }
2577                }
2578              }
2579            })
2580          })
2581
2582        Button("updateSpanStyle3")
2583          .fontSize(12)
2584          .onClick(() => {
2585            this.controller.updateSpanStyle({
2586              start: this.start,
2587              textStyle:
2588              {
2589                fontWeight: FontWeight.Bolder
2590              },
2591              imageStyle: {
2592                size: ["60px", "60px"],
2593                layoutStyle: {
2594                  borderRadius: '-10px',
2595                  margin: '-10px'
2596                }
2597              }
2598            })
2599          })
2600      }
2601      .borderWidth(1)
2602      .borderColor(Color.Red)
2603      .width("100%")
2604      .height("10%")
2605
2606      Row() {
2607        Button('addImageSpan1')
2608          .fontSize(12)
2609          .onClick(() => {
2610            this.controller.addImageSpan($r('app.media.app_icon'), {
2611              imageStyle: {
2612                size: ["80px", "80px"],
2613                layoutStyle: {
2614                  borderRadius: '50px',
2615                  margin: '40px'
2616                }
2617              }
2618            })
2619          })
2620
2621        Button('addImageSpan2')
2622          .fontSize(12)
2623          .onClick(() => {
2624            this.controller.addImageSpan($r('app.media.app_icon'), {
2625              imageStyle: {
2626                size: ["100px", "100px"],
2627                verticalAlign: ImageSpanAlignment.BOTTOM,
2628                layoutStyle: {
2629                  borderRadius: undefined,
2630                  margin: undefined
2631                }
2632              }
2633            })
2634          })
2635
2636        Button('addImageSpan3')
2637          .fontSize(12)
2638          .onClick(() => {
2639            this.controller.addImageSpan($r('app.media.app_icon'), {
2640              imageStyle: {
2641                size: ["60px", "60px"],
2642                verticalAlign: ImageSpanAlignment.BOTTOM,
2643                layoutStyle: {
2644                  borderRadius: { topLeft: '10px', topRight: '20px', bottomLeft: '30px', bottomRight: '40px' },
2645                  margin: { left: '10px', top: '20px', right: '30px', bottom: '40px' }
2646                }
2647              }
2648            })
2649          })
2650      }
2651      .borderWidth(1)
2652      .borderColor(Color.Red)
2653      .width("100%")
2654      .height("10%")
2655
2656      Column() {
2657        RichEditor(this.options)
2658          .onReady(() => {
2659            this.controller.addTextSpan("0123456789",
2660              {
2661                style:
2662                {
2663                  fontColor: Color.Orange,
2664                  fontSize: 30
2665                }
2666              })
2667
2668            this.controller.addImageSpan($r("app.media.app_icon"),
2669              {
2670                imageStyle:
2671                {
2672                  size: ["60px", "60px"],
2673                  verticalAlign: ImageSpanAlignment.BOTTOM,
2674                  layoutStyle: {
2675                    borderRadius: { topLeft: '10px', topRight: '20px', bottomLeft: '30px', bottomRight: '40px' },
2676                    margin: { left: '10px', top: '20px', right: '30px', bottom: '40px' }
2677                  }
2678                }
2679              })
2680
2681            this.controller.addTextSpan("0123456789",
2682              {
2683                style:
2684                {
2685                  fontColor: Color.Black,
2686                  fontSize: 30
2687                }
2688              })
2689          })
2690          .onSelect((value: RichEditorSelection) => {
2691            this.start = value.selection[0];
2692            this.end = value.selection[1];
2693            this.message = "[" + this.start + ", " + this.end + "]"
2694          })
2695          .aboutToIMEInput((value: RichEditorInsertValue) => {
2696            console.log("---------------------- aboutToIMEInput ----------------------")
2697            console.log("insertOffset:" + value.insertOffset)
2698            console.log("insertValue:" + value.insertValue)
2699            return true;
2700          })
2701          .onIMEInputComplete((value: RichEditorTextSpanResult) => {
2702            console.log("---------------------- onIMEInputComplete ---------------------")
2703            console.log("spanIndex:" + value.spanPosition.spanIndex)
2704            console.log("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]")
2705            console.log("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]")
2706            console.log("value:" + value.value)
2707          })
2708          .aboutToDelete((value: RichEditorDeleteValue) => {
2709            console.log("---------------------- aboutToDelete --------------------------")
2710            console.log("offset:" + value.offset)
2711            console.log("direction:" + value.direction)
2712            console.log("length:" + value.length)
2713            value.richEditorDeleteSpans.forEach(item => {
2714              console.log("---------------------- item --------------------------")
2715              console.log("spanIndex:" + item.spanPosition.spanIndex)
2716              console.log("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]")
2717              console.log("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]")
2718              if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') {
2719                console.log("image:" + (item as RichEditorImageSpanResult).valueResourceStr)
2720              } else {
2721                console.log("text:" + (item as RichEditorTextSpanResult).value)
2722              }
2723            })
2724            return true;
2725          })
2726          .onDeleteComplete(() => {
2727            console.log("---------------------- onDeleteComplete ------------------------")
2728          })
2729          .borderWidth(1)
2730          .borderColor(Color.Green)
2731          .width("100%")
2732          .height('80.00%')
2733      }
2734      .borderWidth(1)
2735      .borderColor(Color.Red)
2736      .width("100%")
2737      .height("70%")
2738    }
2739  }
2740}
2741```
2742![ImageSpanStyle](figures/richEditorImageSpanStyle.gif)
2743
2744### 示例5
2745
2746```ts
2747// xxx.ets
2748@Entry
2749@Component
2750struct Index {
2751  controller: RichEditorController = new RichEditorController()
2752  options: RichEditorOptions = { controller: this.controller };
2753  @State textFlag: string = "TextFlag";
2754
2755  build() {
2756    Column() {
2757      Column() {
2758        Text(this.textFlag)
2759          .copyOption(CopyOptions.InApp)
2760          .fontSize(50)
2761      }
2762      Divider()
2763      Column() {
2764        RichEditor(this.options)
2765          .onReady(() => {
2766            this.controller.addTextSpan('Area1\n', {
2767              style:
2768              {
2769                fontColor: Color.Orange,
2770                fontSize: 50
2771              },
2772              gesture:
2773              {
2774                onClick: () => {
2775                  this.textFlag = "Area1 is onClick."
2776                },
2777                onLongPress: () => {
2778                  this.textFlag = "Area1 is onLongPress."
2779                }
2780              }
2781            })
2782
2783            this.controller.addTextSpan('Area2\n', {
2784              style:
2785              {
2786                fontColor: Color.Blue,
2787                fontSize: 50
2788              },
2789              gesture:
2790              {
2791                onClick: () => {
2792                  this.textFlag = "Area2 is onClick."
2793                },
2794                onLongPress: () => {
2795                  this.textFlag = "Area2 is onLongPress."
2796                }
2797              }
2798            })
2799
2800            this.controller.addImageSpan($r("app.media.icon"),
2801              {
2802                imageStyle:
2803                {
2804                  size: ["100px", "100px"],
2805                  layoutStyle: {
2806                    margin: 5,
2807                    borderRadius: 15
2808                  }
2809                },
2810                gesture:
2811                {
2812                  onClick: () => {
2813                    this.textFlag = "ImageSpan is onClick."
2814                  },
2815                  onLongPress: () => {
2816                    this.textFlag = "ImageSpan is onLongPress."
2817                  }
2818                }
2819              })
2820          })
2821      }
2822      .borderWidth(1)
2823      .borderColor(Color.Red)
2824      .width("100%")
2825      .height("70%")
2826    }
2827  }
2828}
2829```
2830![OnClickAndLongPress](figures/richEditorOnClickAndLongPress.gif)
2831
2832### 示例6
2833
2834```ts
2835// xxx.ets
2836@Entry
2837@Component
2838struct Index {
2839  controller: RichEditorController = new RichEditorController();
2840  private spanParagraphs: RichEditorParagraphResult[] = [];
2841
2842  build() {
2843    Column() {
2844      RichEditor({ controller: this.controller })
2845        .onReady(() => {
2846          this.controller.addTextSpan("0123456789\n", {
2847            style: {
2848              fontColor: Color.Pink,
2849              fontSize: "32",
2850            },
2851            paragraphStyle: {
2852              textAlign: TextAlign.Start,
2853              leadingMargin: 16
2854            }
2855          })
2856          this.controller.addTextSpan("0123456789")
2857        })
2858        .width("80%")
2859        .height("30%")
2860        .border({ width: 1, radius: 5 })
2861        .draggable(false)
2862
2863      Column({ space: 5 }) {
2864        Button("段落左对齐").onClick(() => {
2865          this.controller.updateParagraphStyle({ start: -1, end: -1,
2866            style: {
2867              textAlign: TextAlign.Start,
2868            }
2869          })
2870        })
2871
2872        Button("段落右对齐").onClick(() => {
2873          this.controller.updateParagraphStyle({ start: -1, end: -1,
2874            style: {
2875              textAlign: TextAlign.End,
2876            }
2877          })
2878        })
2879
2880        Button("段落居中").onClick(() => {
2881          this.controller.updateParagraphStyle({ start: -1, end: -1,
2882            style: {
2883              textAlign: TextAlign.Center,
2884            }
2885          })
2886        })
2887        Divider()
2888        Button("getParagraphs").onClick(() => {
2889          this.spanParagraphs = this.controller.getParagraphs({ start: -1, end: -1 })
2890          console.log("RichEditor getParagraphs:" + JSON.stringify(this.spanParagraphs))
2891        })
2892
2893        Button("UpdateSpanStyle1").onClick(() => {
2894          this.controller.updateSpanStyle({ start: -1, end: -1,
2895            textStyle: {
2896              fontColor: Color.Brown,
2897              fontSize: 20
2898            }
2899          })
2900        })
2901
2902        Button("UpdateSpanStyle2").onClick(() => {
2903          this.controller.updateSpanStyle({ start: -1, end: -1,
2904            textStyle: {
2905              fontColor: Color.Green,
2906              fontSize: 30
2907            }
2908          })
2909        })
2910      }
2911    }
2912  }
2913}
2914```
2915![TextAlignAndGetParagraphInfo](figures/richEditorTextAlignAndGetParagraphInfo.gif)
2916
2917### 示例7
2918
2919```ts
2920// xxx.ets
2921import { font } from '@kit.ArkUI'
2922
2923const canvasWidth = 1000
2924const canvasHeight = 100
2925const Indentation = 40
2926class LeadingMarginCreator {
2927  private settings: RenderingContextSettings = new RenderingContextSettings(true)
2928  private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(canvasWidth, canvasHeight)
2929  private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings)
2930  public static instance: LeadingMarginCreator = new LeadingMarginCreator()
2931
2932  // 获得字体字号级别,分别是从0到4级
2933  public getFontSizeLevel(fontSize: number) {
2934    const fontScaled: number = Number(fontSize) / 16
2935
2936    enum FontSizeScaleThreshold {
2937      SMALL = 0.9,
2938      NORMAL = 1.1,
2939      LEVEL_1_LARGE = 1.2,
2940      LEVEL_2_LARGE = 1.4,
2941      LEVEL_3_LARGE = 1.5
2942    }
2943
2944    let fontSizeLevel: number = 1
2945
2946    if (fontScaled < FontSizeScaleThreshold.SMALL) {
2947      fontSizeLevel = 0
2948    } else if (fontScaled < FontSizeScaleThreshold.NORMAL) {
2949      fontSizeLevel = 1
2950    } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) {
2951      fontSizeLevel = 2
2952    } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) {
2953      fontSizeLevel = 3
2954    } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) {
2955      fontSizeLevel = 4
2956    } else {
2957      fontSizeLevel = 1
2958    }
2959
2960    return fontSizeLevel
2961  }
2962  // 获得字体字号级别,分别是从0到4级
2963  public getmarginLevel(Width: number) {
2964    let marginlevel: number = 1
2965    if (Width == 40) {
2966      marginlevel = 2.0
2967    } else if (Width == 80) {
2968      marginlevel = 1.0
2969    } else if (Width == 120) {
2970      marginlevel = 2/3
2971    } else if (Width == 160) {
2972      marginlevel = 0.5
2973    } else if (Width == 200) {
2974      marginlevel = 0.4
2975    }
2976    return marginlevel
2977  }
2978
2979  public genStrMark(fontSize: number, str: string): PixelMap {
2980    this.offContext = this.offscreenCanvas.getContext("2d", this.settings)
2981    this.clearCanvas()
2982    this.offContext.font = fontSize + 'vp sans-serif'
2983    this.offContext.fillText(str + '.', 0, fontSize * 0.9)
2984    return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize)
2985  }
2986
2987  public genSquareMark(fontSize: number): PixelMap {
2988    this.offContext = this.offscreenCanvas.getContext("2d", this.settings)
2989    this.clearCanvas()
2990    const coordinate = fontSize * (1 - 1 / 1.5) / 2
2991    const sideLength = fontSize / 1.5
2992    this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength)
2993    return this.offContext.getPixelMap(0, 0, fontSize, fontSize)
2994  }
2995
2996  // 生成圆圈符号
2997  public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap {
2998    const indentLevel = level ?? 1
2999    const offsetLevel = [22, 28, 32, 34, 38]
3000    const fontSizeLevel = this.getFontSizeLevel(fontSize)
3001    const marginlevel = this.getmarginLevel(width)
3002    const newCanvas = new OffscreenCanvas(canvasWidth, canvasHeight)
3003    const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings)
3004    const centerCoordinate = 50
3005    const radius = 10
3006    this.clearCanvas()
3007    newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI)
3008    newOffContext.fillStyle = '66FF0000'
3009    newOffContext.fill()
3010    return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100)
3011  }
3012
3013  private clearCanvas() {
3014    this.offContext.clearRect(0, 0, canvasWidth, canvasHeight)
3015  }
3016}
3017
3018@Entry
3019@Component
3020struct Index {
3021  controller: RichEditorController = new RichEditorController()
3022  options: RichEditorOptions = { controller: this.controller }
3023  private leadingMarkCreatorInstance = LeadingMarginCreator.instance
3024  private fontNameRawFile: string = 'MiSans-Bold'
3025  @State fs: number = 30
3026  @State cl: number = Color.Black
3027  private leftMargin: Dimension = 0
3028  private richEditorTextStyle: RichEditorTextStyle = {}
3029
3030  aboutToAppear() {
3031    font.registerFont({
3032      familyName: 'MiSans-Bold',
3033      familySrc: '/font/MiSans-Bold.ttf'
3034    })
3035  }
3036
3037  build() {
3038    Scroll() {
3039      Column() {
3040        RichEditor(this.options)
3041          .onReady(() => {
3042            this.controller.addTextSpan("0123456789\n",
3043              {
3044                style:
3045                {
3046                  fontWeight: 'medium',
3047                  fontFamily: this.fontNameRawFile,
3048                  fontColor: Color.Red,
3049                  fontSize: 50,
3050                  fontStyle: FontStyle.Italic,
3051                  decoration: { type: TextDecorationType.Underline, color: Color.Green }
3052                }
3053              })
3054
3055            this.controller.addTextSpan("abcdefg",
3056              {
3057                style:
3058                {
3059                  fontWeight: FontWeight.Lighter,
3060                  fontFamily: 'HarmonyOS Sans',
3061                  fontColor: 'rgba(0,128,0,0.5)',
3062                  fontSize: 30,
3063                  fontStyle: FontStyle.Normal,
3064                  decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' }
3065                }
3066              })
3067          })
3068          .borderWidth(1)
3069          .borderColor(Color.Green)
3070          .width("100%")
3071          .height("50%")
3072
3073        Row({ space: 5 }) {
3074          Button('setTypingStyle1')
3075            .fontSize(10)
3076            .onClick(() => {
3077              this.controller.setTypingStyle(
3078                {
3079                  fontWeight: 'medium',
3080                  fontFamily: this.fontNameRawFile,
3081                  fontColor: Color.Blue,
3082                  fontSize: 50,
3083                  fontStyle: FontStyle.Italic,
3084                  decoration: { type: TextDecorationType.Underline, color: Color.Green }
3085                })
3086            })
3087
3088          Button('setTypingStyle2')
3089            .fontSize(10)
3090            .onClick(() => {
3091              this.controller.setTypingStyle(
3092                {
3093                  fontWeight: FontWeight.Lighter,
3094                  fontFamily: 'HarmonyOS Sans',
3095                  fontColor: Color.Green,
3096                  fontSize: '30',
3097                  fontStyle: FontStyle.Normal,
3098                  decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' }
3099                })
3100            })
3101        }
3102        Divider()
3103        Button("getTypingStyle").onClick(() => {
3104          this.richEditorTextStyle = this.controller.getTypingStyle()
3105          console.log("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle))
3106        })
3107        Divider()
3108        Row({ space: 5 }) {
3109          Button("向右列表缩进").onClick(() => {
3110            let margin = Number(this.leftMargin)
3111            if (margin < 200) {
3112              margin += Indentation
3113              this.leftMargin = margin
3114            }
3115            this.controller.updateParagraphStyle({
3116              start: -10,
3117              end: -10,
3118              style: {
3119                leadingMargin : {
3120                  pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1),
3121                  size: [margin, 40]
3122                }
3123              }
3124            })
3125          })
3126
3127          Button("向左列表缩进").onClick(() => {
3128            let margin = Number(this.leftMargin)
3129            if (margin > 0) {
3130              margin -= Indentation
3131              this.leftMargin = margin
3132            }
3133            this.controller.updateParagraphStyle({
3134              start: -10,
3135              end: -10,
3136              style: {
3137                leadingMargin : {
3138                  pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1),
3139                  size: [margin, 40]
3140                }
3141              }
3142            })
3143          })
3144        }
3145        Divider()
3146        Row({ space: 5 }) {
3147          Button("向右空白缩进").onClick(() => {
3148            let margin = Number(this.leftMargin)
3149            if (margin < 200) {
3150              margin += Indentation
3151              this.leftMargin = margin
3152            }
3153            this.controller.updateParagraphStyle({
3154              start: -10,
3155              end: -10,
3156              style: {
3157                leadingMargin: margin
3158              }
3159            })
3160          })
3161
3162          Button("向左空白缩进").onClick(() => {
3163            let margin = Number(this.leftMargin)
3164            if (margin > 0) {
3165              margin -= Indentation
3166              this.leftMargin = margin
3167            }
3168            this.controller.updateParagraphStyle({
3169              start: -10,
3170              end: -10,
3171              style: {
3172                leadingMargin: margin
3173              }
3174            })
3175          })
3176        }
3177      }.borderWidth(1).borderColor(Color.Red)
3178    }
3179  }
3180}
3181```
3182![UpdateParagraphAndTypingStyle](figures/richEditorUpdateParagraphAndTypingStyle.gif)
3183
3184### 示例8
3185``` ts
3186@Entry
3187@Component
3188struct Index {
3189  controller: RichEditorController = new RichEditorController();
3190  options: RichEditorOptions = { controller: this.controller };
3191  private start: number = -1;
3192  private end: number = -1;
3193  @State message: string = "[-1, -1]"
3194  @State content: string = ""
3195  @State visable :number = 0;
3196  @State index:number = 0;
3197  @State offsetx: number = 0;
3198  @State textShadows : (ShadowOptions | Array<ShadowOptions> ) =
3199    [{ radius: 10, color: Color.Red, offsetX: 10, offsetY: 0 },{ radius: 10, color: Color.Black, offsetX: 20, offsetY: 0 },
3200      { radius: 10, color: Color.Brown, offsetX: 30, offsetY: 0 },{ radius: 10, color: Color.Green, offsetX: 40, offsetY: 0 },
3201      { radius: 10, color: Color.Yellow, offsetX: 100, offsetY: 0 }]
3202  @State textshadowOf : ShadowOptions[] = []
3203  build() {
3204    Column() {
3205      Column() {
3206        Text("selection range:").width("100%")
3207        Text() {
3208          Span(this.message)
3209        }.width("100%")
3210        Text("selection content:").width("100%")
3211        Text() {
3212          Span(this.content)
3213        }.width("100%")
3214      }
3215      .borderWidth(1)
3216      .borderColor(Color.Red)
3217      .width("100%")
3218      .height("20%")
3219      Row() {
3220        Button("更新样式: 加粗 & 文本阴影").onClick(() => {
3221          this.controller.updateSpanStyle({
3222            start: this.start,
3223            end: this.end,
3224            textStyle:
3225            {
3226              fontWeight: FontWeight.Bolder,
3227              textShadow: this.textShadows
3228            }
3229          })
3230        })
3231      }
3232      .borderWidth(1)
3233      .borderColor(Color.Red)
3234      .width("100%")
3235      .height("10%")
3236      Column() {
3237        RichEditor(this.options)
3238          .onReady(() => {
3239            this.controller.addTextSpan("0123456789",
3240              {
3241                style:
3242                {
3243                  fontColor: Color.Orange,
3244                  fontSize: 30,
3245                  textShadow: { radius: 10, color: Color.Blue, offsetX: 10, offsetY: 0 }
3246                }
3247              })
3248          })
3249          .borderWidth(1)
3250          .borderColor(Color.Green)
3251          .width("100%")
3252          .height("30%")
3253      }
3254      .borderWidth(1)
3255      .borderColor(Color.Red)
3256      .width("100%")
3257      .height("70%")
3258    }
3259  }
3260}
3261```
3262
3263![TextshadowExample](figures/rich_editor_textshadow.gif)
3264
3265### 示例9
3266``` ts
3267@Builder
3268function placeholderBuilder2() {
3269  Row({ space: 2 }) {
3270    Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 })
3271    Text('okokokok').fontSize(10)
3272  }.width('20%').height(50).padding(10).backgroundColor(Color.Red)
3273}
3274
3275// xxx.ets
3276@Entry
3277@Component
3278struct Index {
3279  controller: RichEditorController = new RichEditorController();
3280  option: RichEditorOptions = { controller: this.controller };
3281  private start: number = 2;
3282  private end: number = 4;
3283  @State message: string = "[-1, -1]"
3284  @State content: string = ""
3285  private my_offset: number | undefined = undefined
3286  private my_builder: CustomBuilder = undefined
3287  @BuilderParam my_builder2:() => void = placeholderBuilder2;
3288
3289  @Builder
3290  placeholderBuilder() {
3291    Row({ space: 2 }) {
3292      Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 })
3293      Text('Custom Popup').fontSize(10)
3294    }.width(100).height(50).padding(5)
3295  }
3296
3297  @Builder
3298  placeholderBuilder3() {
3299    Text("hello").padding('20').borderWidth(1).width('100%')
3300  }
3301
3302  @Builder
3303  placeholderBuilder4() {
3304    Column() {
3305      Column({ space: 5 }) {
3306        Text('direction:Row').fontSize(9).fontColor(0xCCCCCC).width('90%')
3307        Flex({ direction: FlexDirection.Row }) { // 子组件在容器主抽上行布局
3308          Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
3309          Text('1').width('20%').height(50).backgroundColor(0xD2B48C)
3310          Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
3311          Text('1').width('20%').height(50).backgroundColor(0xD2B48C)
3312        }
3313        .height(70)
3314        .width('90%')
3315        .padding(10)
3316        .backgroundColor(0xAFEEEE)
3317
3318        Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%')
3319        Flex({ direction: FlexDirection.RowReverse }) { // 子组件在容器主抽上反向行布局
3320          Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
3321          Text('1').width('20%').height(50).backgroundColor(0xD2B48C)
3322          Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
3323          Text('1').width('20%').height(50).backgroundColor(0xD2B48C)
3324        }
3325        .height(70)
3326        .width('90%')
3327        .padding(10)
3328        .backgroundColor(0xAFEEEE)
3329
3330        Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%')
3331        Flex({ direction: FlexDirection.Column }) { // 子组件在容器主抽上列布局
3332          Text('1').width('20%').height(40).backgroundColor(0xF5DEB3)
3333          Text('1').width('20%').height(40).backgroundColor(0xD2B48C)
3334          Text('1').width('20%').height(40).backgroundColor(0xF5DEB3)
3335          Text('1').width('20%').height(40).backgroundColor(0xD2B48C)
3336        }
3337        .height(160)
3338        .width('90%')
3339        .padding(10)
3340        .backgroundColor(0xAFEEEE)
3341
3342        Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%')
3343        Flex({ direction: FlexDirection.ColumnReverse }) { // 子组件在容器主抽上反向列布局
3344          Text('1').width('20%').height(40).backgroundColor(0xF5DEB3)
3345          Text('1').width('20%').height(40).backgroundColor(0xD2B48C)
3346          Text('1').width('20%').height(40).backgroundColor(0xF5DEB3)
3347          Text('1').width('20%').height(40).backgroundColor(0xD2B48C)
3348        }
3349        .height(160)
3350        .width('90%')
3351        .padding(10)
3352        .backgroundColor(0xAFEEEE)
3353      }.width('100%').margin({ top: 5 })
3354    }.width('100%')
3355  }
3356
3357  @Builder
3358  MyMenu() {
3359    Menu() {
3360      MenuItem({ startIcon: $r("app.media.icon"), content: "菜单选项1" })
3361      MenuItem({ startIcon: $r("app.media.icon"), content: "菜单选项2" })
3362        .enabled(false)
3363    }
3364  }
3365
3366  build() {
3367    Column() {
3368      Column() {
3369        Text("selection range:").width("100%")
3370        Text() {
3371          Span(this.message)
3372        }.width("100%")
3373
3374        Text("selection content:").width("100%")
3375        Text() {
3376          Span(this.content)
3377        }.width("100%")
3378      }
3379      .borderWidth(1)
3380      .borderColor(Color.Red)
3381      .width("100%")
3382      .height("20%")
3383
3384      Row() {
3385        Button("获取选择内容 getSpans").onClick(() => {
3386          console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 })))
3387          console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 })))
3388          this.content = ""
3389          this.controller.getSpans({
3390            start: this.start,
3391            end: this.end
3392          }).forEach(item => {
3393            if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') {
3394              if ((item as RichEditorImageSpanResult).valueResourceStr == "") {
3395                console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " +
3396                  (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1])
3397              } else {
3398                console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " +
3399                  (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " +
3400                  (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1])
3401              }
3402            } else {
3403              this.content += (item as RichEditorTextSpanResult).value;
3404              this.content += "\n"
3405              console.info("text span: " + (item as RichEditorTextSpanResult).value)
3406            }
3407          })
3408        })
3409        Button("获取选择内容 getSelection").onClick(() => {
3410          this.content = "";
3411          let select = this.controller.getSelection()
3412          console.info("selection start " + select.selection[0] + " end " + select.selection[1])
3413          select.spans.forEach(item => {
3414            if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') {
3415              if ((item as RichEditorImageSpanResult).valueResourceStr == "") {
3416                console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " +
3417                  (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1])
3418              } else {
3419                console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " +
3420                  (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " +
3421                  (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1])
3422              }
3423            } else {
3424              this.content += (item as RichEditorTextSpanResult).value;
3425              this.content += "\n"
3426              console.info("text span: " + (item as RichEditorTextSpanResult).value)
3427            }
3428          })
3429        })
3430        Button("删除选择内容").onClick(() => {
3431          this.controller.deleteSpans({
3432            start: this.start,
3433            end: this.end
3434          })
3435        })
3436      }
3437      .borderWidth(1)
3438      .borderColor(Color.Red)
3439      .width("100%")
3440      .height("10%")
3441
3442      Column() {
3443        RichEditor(this.option)
3444          .onReady(() => {
3445            this.controller.addTextSpan("0123456789",
3446              {
3447                style:
3448                {
3449                  fontColor: Color.Orange,
3450                  fontSize: 30
3451                }
3452              })
3453            this.controller.addImageSpan($r("app.media.icon"),
3454              {
3455                imageStyle:
3456                {
3457                  size: ["57px", "57px"]
3458                }
3459              })
3460          })
3461          .onSelect((value: RichEditorSelection) => {
3462            this.start = value.selection[0];
3463            this.end = value.selection[1];
3464            this.message = "[" + this.start + ", " + this.end + "]"
3465            console.info("onSelect="+JSON.stringify(value))
3466          })
3467          .aboutToIMEInput((value: RichEditorInsertValue) => {
3468            console.log("---------------------- aboutToIMEInput --------------------")
3469            console.info("aboutToIMEInput="+JSON.stringify(value))
3470            console.log("insertOffset:" + value.insertOffset)
3471            console.log("insertValue:" + value.insertValue)
3472            return true;
3473          })
3474          .onIMEInputComplete((value: RichEditorTextSpanResult) => {
3475            console.log("---------------------- onIMEInputComplete --------------------")
3476            console.info("onIMEInputComplete="+JSON.stringify(value))
3477            console.log("spanIndex:" + value.spanPosition.spanIndex)
3478            console.log("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]")
3479            console.log("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]")
3480            console.log("value:" + value.value)
3481          })
3482          .aboutToDelete((value: RichEditorDeleteValue) => {
3483            value.richEditorDeleteSpans.forEach(item => {
3484              console.log("---------------------- item --------------------")
3485              console.info("spanIndex=" + item.spanPosition.spanIndex)
3486              console.log("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]")
3487              console.log("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]")
3488              if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') {
3489                if ((item as RichEditorImageSpanResult).valueResourceStr == "") {
3490                  console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " +
3491                  (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1])
3492                } else {
3493                  console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " +
3494                  (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " +
3495                  (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1])
3496                }
3497              } else {
3498                console.info("delete text: " + (item as RichEditorTextSpanResult).value)
3499              }
3500            })
3501            return true;
3502          })
3503          .borderWidth(1)
3504          .borderColor(Color.Green)
3505          .width("100%")
3506          .height("30%")
3507
3508        Button("add span")
3509          .onClick(() => {
3510            let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset })
3511            console.info('addBuilderSpan return ' + num)
3512          })
3513        Button("add image")
3514          .onClick(() => {
3515            let num = this.controller.addImageSpan($r("app.media.icon"), {
3516              imageStyle: {
3517                size: ["50px", "50px"],
3518                verticalAlign: ImageSpanAlignment.BOTTOM,
3519                layoutStyle: {
3520                  borderRadius: undefined,
3521                  margin: undefined
3522                }
3523              }
3524            })
3525            console.info('addImageSpan return' + num)
3526          })
3527        Row() {
3528          Button('builder1').onClick(() => {
3529            this.my_builder = () => {
3530              this.placeholderBuilder()
3531            }
3532          })
3533          Button('builder2').onClick(() => {
3534            this.my_builder = () => {
3535              this.my_builder2()
3536            }
3537          })
3538          Button('builder3').onClick(() => {
3539            this.my_builder = () => {
3540              this.placeholderBuilder3()
3541            }
3542          })
3543          Button('builder4').onClick(() => {
3544            this.my_builder = () => {
3545              this.placeholderBuilder4()
3546            }
3547          })
3548        }
3549      }
3550      .borderWidth(1)
3551      .borderColor(Color.Red)
3552      .width("100%")
3553      .height("70%")
3554    }
3555  }
3556}
3557```
3558![AddBuilderSpanExample](figures/rich_editor_addBuilderSpan.gif)
3559
3560### 示例10
3561enableDataDetector和dataDetectorConfig使用示例
3562
3563```ts
3564@Entry
3565@Component
3566struct TextExample7 {
3567  controller: RichEditorController = new RichEditorController();
3568  options: RichEditorOptions = { controller: this.controller };
3569  @State phoneNumber: string = '(86) (755) ********';
3570  @State url: string = 'www.********.com';
3571  @State email: string = '***@example.com';
3572  @State address: string = 'XX省XX市XX区XXXX';
3573  @State enableDataDetector: boolean = true;
3574  @State enablePreviewText: boolean = false;
3575  @State types: TextDataDetectorType[] = [];
3576
3577  build() {
3578    Row() {
3579      Column() {
3580        RichEditor(this.options)
3581          .onReady(() => {
3582            this.controller.addTextSpan('电话号码:' + this.phoneNumber + '\n',
3583              {
3584                style:
3585                {
3586                  fontSize: 30
3587                }
3588              })
3589            this.controller.addTextSpan('链接:' + this.url + '\n',
3590              {
3591                style:
3592                {
3593                  fontSize: 30
3594                }
3595              })
3596            this.controller.addTextSpan('邮箱:' + this.email + '\n',
3597              {
3598                style:
3599                {
3600                  fontSize: 30
3601                }
3602              })
3603            this.controller.addTextSpan('地址:' + this.address,
3604              {
3605                style:
3606                {
3607                  fontSize: 30
3608                }
3609              })
3610          })
3611          .copyOptions(CopyOptions.InApp)
3612          .enableDataDetector(this.enableDataDetector)
3613          .dataDetectorConfig({types : this.types, onDetectResultUpdate: (result: string)=>{}})
3614          .enablePreviewText(this.enablePreviewText)
3615          .borderWidth(1)
3616          .padding(10)
3617          .width('100%')
3618      }
3619      .width('100%')
3620    }
3621  }
3622}
3623```
3624### 示例11
3625caretColor和selectedBackgroundColor使用示例
3626``` ts
3627@Entry
3628@Component
3629struct RichEditorDemo {
3630  @State color: Color|string = ""
3631  controller: RichEditorController = new RichEditorController();
3632  build() {
3633    Column() {
3634      Row(){
3635        Button("改为红色").onClick(() => {
3636          this.color = Color.Red
3637        })
3638      }.margin({top:50})
3639      RichEditor({ controller: this.controller })
3640        .onReady(()=>{
3641          this.controller.addTextSpan('测试文字测试文字测试文字测试文字测试文字测试文字')
3642        })
3643        .width("100%")
3644        .border({ width: 1, radius: 5 })
3645        .key('RichEditor')
3646        .caretColor(this.color)  //光标颜色
3647        .selectedBackgroundColor(this.color)  //选中背景色
3648        .margin({top:50})
3649    }
3650    .width('100%')
3651  }
3652}
3653```
3654![SetCaretAndSelectedBackgroundColorExample](figures/rich_editor_caret_color.gif)
3655
3656### 示例12
3657lineHeight和letterSpacing使用示例
3658```ts
3659@Entry
3660@Component
3661struct RichEditorDemo03 {
3662  controller: RichEditorController = new RichEditorController();
3663  options: RichEditorOptions = { controller: this.controller };
3664  @State start: number = -1;
3665  @State end: number = -1;
3666  @State LH:number = 50
3667  @State LS:number = 20
3668
3669  build() {
3670    Column() {
3671      Scroll(){
3672        Column(){
3673          Row() {
3674            Button("行高++").onClick(()=>{
3675              this.LH = this.LH + 5
3676              this.controller.updateSpanStyle({
3677                start: this.start,
3678                end: this.end,
3679                textStyle:
3680                {
3681                  lineHeight: this.LH
3682                }
3683              })
3684            })
3685            Button("行高--").onClick(()=>{
3686              this.LH = this.LH - 5
3687              this.controller.updateSpanStyle({
3688                start: this.start,
3689                end: this.end,
3690                textStyle:
3691                {
3692                  lineHeight: this.LH
3693                }
3694              })
3695            })
3696            Button("字符间距++").onClick(()=>{
3697              this.LS = this.LS + 5
3698              this.controller.updateSpanStyle({
3699                start: this.start,
3700                end: this.end,
3701                textStyle:
3702                {
3703                  letterSpacing: this.LS
3704                }
3705              })
3706            })
3707            Button("字符间距--").onClick(()=>{
3708              this.LS = this.LS - 5
3709              this.controller.updateSpanStyle({
3710                start: this.start,
3711                end: this.end,
3712                textStyle:
3713                {
3714                  letterSpacing: this.LS
3715                }
3716              })
3717            })
3718          }
3719        }
3720      }.borderWidth(1)
3721      .borderColor(Color.Red)
3722      .width("100%")
3723      .height("20%")
3724      .margin({top: 20})
3725
3726      Scroll(){
3727        Column() {
3728          Text("LineHeight:" + this.LH).width("100%")
3729          Text("LetterSpacing:" + this.LS).width("100%")
3730        }
3731      }
3732      .borderWidth(1)
3733      .borderColor(Color.Red)
3734      .width("100%")
3735      .height("20%")
3736      .margin({bottom: 20})
3737
3738      Column() {
3739        RichEditor(this.options).clip(true).padding(10)
3740          .onReady(() => {
3741            this.controller.addTextSpan("012345",
3742              {
3743                style:
3744                {
3745                  fontColor: Color.Orange,
3746                  fontSize: 30,
3747                  lineHeight: this.LH,
3748                  letterSpacing: this.LS
3749                }
3750              })
3751            this.controller.addTextSpan("6789",
3752              {
3753                style:
3754                {
3755                  fontColor: Color.Black,
3756                  fontSize: 30,
3757                  lineHeight: this.LH,
3758                  letterSpacing: this.LS
3759                }
3760              })
3761          })
3762          .borderWidth(1)
3763          .borderColor(Color.Green)
3764          .width(400)
3765          .height(400)
3766      }
3767      .borderWidth(1)
3768      .borderColor(Color.Red)
3769      .width("100%")
3770      .height("60%")
3771    }
3772  }
3773}
3774```
3775![AddBuilderSpanExample](figures/richEditorLineHeightAndLetterSpacing.png)
3776
3777### 示例13
3778preventDefault使用示例
3779```ts
3780@Entry
3781@Component
3782struct RichEditorDemo {
3783  controller: RichEditorController = new RichEditorController();
3784  options: RichEditorOptions = { controller: this.controller };
3785
3786  build() {
3787    Column({ space: 2 }) {
3788      RichEditor(this.options)
3789        .onReady(() => {
3790          this.controller.addTextSpan('RichEditor preventDefault')
3791        })
3792        .onPaste((event?: PasteEvent) => {
3793          if (event != undefined && event.preventDefault) {
3794            event.preventDefault();
3795          }
3796        })
3797        .borderWidth(1)
3798        .borderColor(Color.Green)
3799        .width('100%')
3800        .height('40%')
3801    }
3802  }
3803}
3804```
3805![PreventDefaultExample](figures/richEditorPreventDefault.gif)
3806
3807### 示例14
3808
3809当添加“ss01”特性的FontFeature属性时,数字“0”由原来的椭圆形改变为带有倒圆角形。
3810
3811```ts
3812@Entry
3813@Component
3814struct RichEditorExample {
3815  controller: RichEditorController = new RichEditorController();
3816  options: RichEditorOptions = { controller: this.controller };
3817  @State enableDataDetector: boolean = true;
3818  @State types: TextDataDetectorType[] = [];
3819  build() {
3820    Row() {
3821      Column() {
3822        RichEditor(this.options)
3823          .onReady(() => {
3824            this.controller.addTextSpan('This is ss01 off :' + '0000' + '\n',
3825              {
3826                style:
3827                {
3828                  fontSize: 30
3829                }
3830              })
3831            this.controller.addTextSpan('This is ss01 on :' + '0000' + '\n',
3832              {
3833                style:
3834                {
3835                  fontSize: 30,
3836                  fontFeature: "\"ss01\" 1"
3837                }
3838              })
3839          })
3840          .copyOptions(CopyOptions.InApp)
3841          .enableDataDetector(this.enableDataDetector)
3842          .dataDetectorConfig({types : this.types, onDetectResultUpdate: (result: string)=>{}})
3843          .borderWidth(1)
3844          .padding(10)
3845          .width('100%')
3846      }
3847      .width('100%')
3848      .margin({top:150})
3849    }
3850  }
3851}
3852```
3853![FontFeatureExample](figures/richEditorFontFeature.png)
3854
3855### 示例15
3856
3857自定义键盘弹出发生避让示例。
3858
3859```ts
3860@Entry
3861@Component
3862struct RichEditorExample {
3863  controller: RichEditorController = new RichEditorController()
3864  @State height1:string|number = '80%'
3865  @State height2:number = 100
3866  @State supportAvoidance:boolean = true;
3867
3868  // 自定义键盘组件
3869  @Builder CustomKeyboardBuilder() {
3870    Column() {
3871      Row(){
3872        Button('增加特表情包').onClick(() => {
3873          this.controller.addTextSpan("\uD83D\uDE0A",
3874            {
3875              style:
3876              {
3877                fontColor: Color.Orange,
3878              }
3879            })
3880        })
3881      }
3882      Grid() {
3883        ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '#'], (item: number | string) => {
3884          GridItem() {
3885            Button(item + "")
3886              .width(110).onClick(() => {
3887              this.controller.addTextSpan(item + '', {
3888                offset: this.controller.getCaretOffset(),
3889                style:
3890                {
3891                  fontColor: Color.Orange,
3892                  fontSize: 30
3893                }
3894              })
3895              this.controller.setCaretOffset(this.controller.getCaretOffset() + item.toString().length)
3896            })
3897          }
3898        })
3899      }.maxCount(3).columnsGap(10).rowsGap(10).padding(5)
3900    }.backgroundColor(Color.Gray)
3901  }
3902
3903  build() {
3904    Column() {
3905      Row(){
3906        Button("20%")
3907          .fontSize(24)
3908          .onClick(()=>{
3909            this.height1 = "20%"
3910          })
3911        Button("80%")
3912          .fontSize(24)
3913          .margin({left:20})
3914          .onClick(()=>{
3915            this.height1 = "80%"
3916          })
3917      }
3918      .justifyContent(FlexAlign.Center)
3919      .alignItems(VerticalAlign.Bottom)
3920      .height(this.height1)
3921      .width("100%")
3922      .padding({bottom:50})
3923      RichEditor({ controller: this.controller })
3924        // 绑定自定义键盘
3925        .customKeyboard(this.CustomKeyboardBuilder(),{ supportAvoidance: this.supportAvoidance }).margin(10).border({ width: 1 })
3926        .borderWidth(1)
3927        .borderColor(Color.Red)
3928        .width("100%")
3929    }
3930  }
3931}
3932```
3933![CustomRichEditorType](figures/Custom_Rich_Editor.gif)
3934
3935### 示例16
3936
3937onEditingChange,isEditing使用示例。
3938
3939```ts
3940@Entry
3941@Component
3942struct RichEditor_onEditingChange {
3943  controller: RichEditorController = new RichEditorController()
3944  @State controllerIsEditing: boolean = false
3945  @Builder
3946
3947  build() {
3948    Column() {
3949      Row() {
3950        Button("点击查看编辑状态isEditing():").onClick(() => {
3951          this.controllerIsEditing = this.controller.isEditing()
3952        })
3953          .padding(5)
3954        Text('' + this.controllerIsEditing)
3955          .width('100%')
3956          .padding(5)
3957          .fontColor(Color.Orange)
3958          .fontSize(20)
3959      }
3960      RichEditor({ controller: this.controller })
3961        .onEditingChange((isEditing: boolean) => {
3962          console.log("Current Editing Status:" + isEditing)
3963        })
3964        .height(400)
3965        .borderWidth(1)
3966        .borderColor(Color.Red)
3967        .width("100%")
3968    }
3969  }
3970}
3971```
3972
3973![RichEditorOnEditingChange](figures/richEditorOnEditingChange.gif)
3974
3975### 示例17
3976
3977onWillChange,onDidChange,onCut,onCopy使用示例。
3978
3979```ts
3980@Entry
3981@Component
3982struct RichEditorExample {
3983  controller: RichEditorController = new RichEditorController()
3984  build() {
3985    Column() {
3986      RichEditor({ controller: this.controller })
3987        .height(200)
3988        .borderWidth(1)
3989        .borderColor(Color.Red)
3990        .width("100%")
3991        .onReady(() => {
3992          this.controller.addTextSpan('测试文字TestWord', { style: { fontColor: Color.Orange, fontSize: 30 } })
3993          this.controller.updateSpanStyle({
3994            start: -1,
3995            end: -1,
3996            textStyle:
3997            {
3998              fontWeight: FontWeight.Bolder
3999            }
4000          })
4001        })
4002        .onWillChange((value: RichEditorChangeValue) => {
4003          console.log('测试log: onWillChange')
4004          console.log('rangeBefore: ' + JSON.stringify(value.rangeBefore))
4005          console.log('print replacedSpans')
4006          value.replacedSpans.forEach((item: RichEditorTextSpanResult) => {
4007            console.log('spanPosition:' + JSON.stringify(item.spanPosition))
4008            console.log('value:' + item.value)
4009            console.log('textStyle:' + JSON.stringify(item.textStyle))
4010            console.log('offsetInSpan:' + item.offsetInSpan)
4011            console.log('valueResource:' + item.valueResource)
4012            console.log('paragraphStyle:' + JSON.stringify(item.paragraphStyle))
4013          })
4014          console.log('print replacedImageSpans')
4015          value.replacedImageSpans.forEach((item: RichEditorImageSpanResult) => {
4016            console.log('spanPosition:' + JSON.stringify(item.spanPosition))
4017            console.log('valuePixelMap:' + JSON.stringify(item.valuePixelMap))
4018            console.log('valueResourceStr:' + item.valueResourceStr)
4019            console.log('imageStyle:' + JSON.stringify(item.imageStyle))
4020            console.log('offsetInSpan:' + item.offsetInSpan)
4021          })
4022          console.log('print replacedSymbolSpans')
4023          value.replacedSymbolSpans.forEach((item: RichEditorTextSpanResult) => {
4024            console.log('spanPosition:' + JSON.stringify(item.spanPosition))
4025            console.log('value:' + item.value)
4026            console.log('offsetInSpan:' + item.offsetInSpan)
4027            console.log('symbolSpanStyle:' + JSON.stringify(item.symbolSpanStyle))
4028            console.log('valueResource:' + item.valueResource)
4029            console.log('paragraphStyle:' + JSON.stringify(item.paragraphStyle))
4030          })
4031          return true
4032        })
4033        .onDidChange((rangeBefore: TextRange, rangeAfter: TextRange) => {
4034          console.log('测试log: onDidChange')
4035          console.log('rangeBefore:' + JSON.stringify(rangeBefore))
4036          console.log('rangeAfter:' + JSON.stringify(rangeAfter))
4037        })
4038        .onCut((event:CutEvent) => {
4039          event.preventDefault!()
4040          console.log('测试log:onCut')
4041        })
4042        .onCopy((event:CopyEvent) => {
4043          event.preventDefault!()
4044          console.log('测试log:onCopy')
4045        })
4046        .onPaste(()=>{
4047          console.log('测试log:onPaste')
4048        })
4049      Text('测试文字去Hellow')
4050        .lineHeight(50)
4051        .fontSize(24)
4052        .draggable(true)
4053        .onDragStart(()=>{})
4054      TextInput({text:'测试文字NiHao'})
4055        .draggable(true)
4056        .margin(20)
4057    }
4058  }
4059}
4060```
4061### 示例18
4062
4063enterKeyType,onSubmit,stopEditing使用示例。
4064
4065```ts
4066@Entry
4067@Component
4068struct SoftKeyboardEnterTypeExample {
4069  controller: RichEditorController = new RichEditorController()
4070
4071    build() {
4072    Column() {
4073      Button("停止编辑").onClick(()=>{
4074        this.controller.stopEditing()
4075      })
4076      RichEditor({ controller: this.controller })
4077        .margin(10)
4078        .border({ width: 1 })
4079        .height(200)
4080        .borderWidth(1)
4081        .borderColor(Color.Red)
4082        .width("100%")
4083        .enterKeyType(EnterKeyType.Search)
4084        .onSubmit((enterKey: EnterKeyType, event: SubmitEvent) => {
4085          console.log("trigger richeditor onsubmit" + enterKey);
4086          this.controller.addTextSpan(" type["+ enterKey +"] triggerred")
4087          event.keepEditableState();
4088        })
4089    }.height("100%").justifyContent(FlexAlign.Center)
4090  }
4091}
4092```
4093
4094![SoftKeyboardEnterType](figures/richeditorentertype.gif)
4095
4096### 示例19
4097lineBreakStrategy属性值设置、更新、查询使用示例。
4098
4099```ts
4100@Entry
4101@Component
4102struct LineBreakStrategyExample {
4103  controller: RichEditorController = new RichEditorController();
4104  private spanParagraphs: RichEditorParagraphResult[] = [];
4105  @State lineBreakOptionStr: string[] = ['GREEDY', 'HIGH_QUALITY', 'BALANCED']
4106  @State attributeValue: string = ""
4107  @State testStr: string = "0123456789,0123456789,0123456789,0123456789,0123456789."
4108  build() {
4109    Column() {
4110      RichEditor({ controller: this.controller })
4111        .onReady(() => {
4112          this.controller.addTextSpan(this.testStr, {
4113            style: {
4114              fontColor: Color.Black,
4115              fontSize: "32",
4116            },
4117            paragraphStyle: {
4118              textAlign: TextAlign.Start,
4119              lineBreakStrategy: LineBreakStrategy.GREEDY
4120            }
4121          })
4122        })
4123        .width(400)
4124        .height(300)
4125        .margin({bottom:20})
4126        .draggable(false)
4127      Column(){
4128        Text('linebreak属性值为:' + this.attributeValue).fontSize(20).fontColor(Color.Black)
4129      }.margin({bottom: 10})
4130      Column({ space: 10 }) {
4131        Button("设置折行类型GREEDY").onClick(() => {
4132          this.controller.updateParagraphStyle({ start: -1, end: -1,
4133            style: {
4134              lineBreakStrategy: LineBreakStrategy.GREEDY,
4135            }
4136          })
4137        })
4138        Button("设置折行类型HIGH_QUALITY").onClick(() => {
4139          this.controller.updateParagraphStyle({ start: -1, end: -1,
4140            style: {
4141              lineBreakStrategy: LineBreakStrategy.HIGH_QUALITY,
4142            }
4143          })
4144        })
4145        Button("设置折行类型BALANCED").onClick(() => {
4146          this.controller.updateParagraphStyle({ start: -1, end: -1,
4147            style: {
4148              lineBreakStrategy: LineBreakStrategy.BALANCED,
4149            }
4150          })
4151        })
4152        Divider()
4153        Row(){
4154          Button("获取linebreak属性值").onClick(() => {
4155            this.spanParagraphs = this.controller.getParagraphs({ start: -1, end: -1 })
4156            console.log("RichEditor getParagraphs:" + JSON.stringify(this.spanParagraphs))
4157            this.spanParagraphs.forEach(item => {
4158              if(typeof(item as RichEditorParagraphResult)['style'] != 'undefined'){
4159                this.attributeValue = ""
4160                console.info('lineBreakStrategy:'+ JSON.stringify((item as RichEditorParagraphResult)['style']))
4161                this.attributeValue += this.lineBreakOptionStr[Number((item as RichEditorParagraphResult)['style'].lineBreakStrategy)];
4162              }
4163            })
4164          })
4165        }
4166      }
4167    }
4168  }
4169}
4170```
4171
4172![LineBreakStrategy](figures/richEditorLineBreak.gif)
4173
4174### 示例20
4175属性字符串使用示例。
4176
4177```ts
4178import {LengthMetrics} from '@kit.ArkUI'
4179import {image} from '@kit.ImageKit'
4180
4181@Entry
4182@Component
4183struct Index {
4184  stringLength: number = 0;
4185  imagePixelMap: image.PixelMap | undefined = undefined;
4186  @State selection: string = "";
4187  @State content: string = "";
4188  @State range: string = "";
4189  @State replaceString: string = "";
4190  @State rangeBefore: string = "";
4191  @State rangeAfter: string = "";
4192  richEditorStyledString: MutableStyledString = new MutableStyledString("");
4193  textStyle: TextStyle = new TextStyle({
4194    fontWeight: FontWeight.Lighter,
4195    fontFamily: 'HarmonyOS Sans',
4196    fontColor: Color.Green,
4197    fontSize: LengthMetrics.vp(30),
4198    fontStyle: FontStyle.Normal
4199  })
4200  fontStyle1: TextStyle = new TextStyle({
4201    fontColor: Color.Blue
4202  });
4203  fontStyle2: TextStyle = new TextStyle({
4204    fontWeight: FontWeight.Bolder,
4205    fontFamily: 'Arial',
4206    fontColor: Color.Orange,
4207    fontSize: LengthMetrics.vp(30),
4208    fontStyle: FontStyle.Italic
4209  })
4210
4211  controller1: RichEditorController = new RichEditorController()
4212  options1: RichEditorOptions = {
4213    controller: this.controller1
4214  };
4215  // 创建属性字符串对象
4216  mutableStyledString: MutableStyledString = new MutableStyledString("初始属性字符串",
4217    [{
4218      start: 0,
4219      length: 5,
4220      styledKey: StyledStringKey.FONT,
4221      styledValue: this.fontStyle1
4222    }]);
4223  styledString: StyledString = new StyledString("插入属性字符串",
4224    [{
4225      start: 2,
4226      length: 4,
4227      styledKey: StyledStringKey.FONT,
4228      styledValue: this.fontStyle2
4229    }]);
4230  controller: RichEditorStyledStringController = new RichEditorStyledStringController();
4231  options: RichEditorStyledStringOptions = {
4232    controller: this.controller
4233  };
4234  // 文本内容变化回调
4235  contentChangedListener: StyledStringChangedListener = {
4236    onWillChange: (value: StyledStringChangeValue) => {
4237      this.range = '[ ' + value.range.start + ' , ' + value.range.end + ' ]';
4238      this.replaceString = value.replacementString.getString();
4239      return true;
4240    },
4241    onDidChange: (rangeBefore, rangeAfter) => {
4242      this.rangeBefore = '[ ' + rangeBefore.start + ' , ' + rangeBefore.end + ' ]';
4243      this.rangeAfter = '[ ' + rangeAfter.start + ' , ' + rangeAfter.end + ' ]';
4244    }
4245  }
4246
4247  async aboutToAppear() {
4248    console.info("aboutToAppear initial imagePixelMap");
4249    this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.app_icon'));
4250  }
4251
4252  private async getPixmapFromMedia(resource: Resource) {
4253    let unit8Array = await getContext(this)?.resourceManager?.getMediaContent({
4254      bundleName: resource.bundleName,
4255      moduleName: resource.moduleName,
4256      id: resource.id
4257    })
4258    let imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength))
4259    let createPixelMap: image.PixelMap = await imageSource.createPixelMap({
4260      desiredPixelFormat: image.PixelMapFormat.RGBA_8888
4261    })
4262    await imageSource.release()
4263    return createPixelMap
4264  }
4265
4266  build() {
4267    Column({space: 6}) {
4268      Column() {
4269        Text("选中区信息")
4270          .fontSize(20)
4271          .width("100%")
4272        Text("selection range: " + this.selection).width("100%")
4273        Text("selection content: " + this.content).width("100%")
4274      }
4275      .width("100%")
4276      .height("10%")
4277
4278      Column() {
4279        Text("onWillChange回调信息")
4280          .fontSize(20)
4281          .width("100%")
4282        Text("range: " + this.range).width("100%")
4283        Text("replacementString: " + this.replaceString).width("100%")
4284        Text("onWillChange回调信息")
4285          .fontSize(20)
4286          .width("100%")
4287        Text("rangeBefore: " + this.rangeBefore).width("100%")
4288        Text("rangeAfter: " + this.rangeAfter).width("100%")
4289      }
4290      .borderWidth(1)
4291      .borderColor(Color.Black)
4292      .width("100%")
4293      .height("20%")
4294
4295      RichEditor(this.options)
4296        .onReady(() => {
4297          // 注册文本变化回调
4298          this.controller.onContentChanged(this.contentChangedListener);
4299          // 设定组件展示的属性字符串
4300          this.controller.setStyledString(this.mutableStyledString);
4301        })
4302        .height("20%")
4303        .width("100%")
4304
4305      RichEditor(this.options1)
4306        .onReady(() => {
4307          this.controller1.addTextSpan("把这些文字转换成属性字符串");
4308        })
4309        .height("10%")
4310        .width("100%")
4311        .borderWidth(1)
4312        .borderColor(Color.Black)
4313
4314      Row({space: 2}) {
4315        Button("插入图片")
4316          .stateEffect(true)
4317          .onClick(() => {
4318            if (this.imagePixelMap !== undefined) {
4319              let imageStyledString = new MutableStyledString(new ImageAttachment({
4320                value: this.imagePixelMap,
4321                size: {
4322                  width: 50,
4323                  height: 50
4324                },
4325                layoutStyle: {
4326                  borderRadius: LengthMetrics.vp(10)
4327                },
4328                verticalAlign: ImageSpanAlignment.BASELINE,
4329                objectFit: ImageFit.Contain
4330              }))
4331              // 获取组件展示的属性字符串
4332              this.richEditorStyledString = this.controller.getStyledString();
4333              this.richEditorStyledString.appendStyledString(imageStyledString);
4334              // 使插入图片后的属性字符串展示在组件上
4335              this.controller.setStyledString(this.richEditorStyledString);
4336              this.controller.setCaretOffset(this.richEditorStyledString.length);
4337            }
4338          })
4339        Button("插入文本").onClick(() => {
4340          // 获取组件展示的属性字符串
4341          this.richEditorStyledString = this.controller.getStyledString();
4342          this.richEditorStyledString.appendStyledString(this.styledString);
4343          // 使插入文本后的属性字符串展示在组件上
4344          this.controller.setStyledString(this.richEditorStyledString);
4345          this.controller.setCaretOffset(this.richEditorStyledString.length);
4346        })
4347        Button("删除选中内容").onClick(() => {
4348          // 获取选中范围
4349          let richEditorSelection = this.controller.getSelection();
4350          let start = richEditorSelection.start ? richEditorSelection.start : 0;
4351          let end = richEditorSelection.end ? richEditorSelection.end : 0;
4352          // 获取组件展示的属性字符串
4353          this.richEditorStyledString = this.controller.getStyledString();
4354          this.richEditorStyledString.removeString(start, end - start);
4355          // 使删除内容后的属性字符串展示在组件上
4356          this.controller.setStyledString(this.richEditorStyledString);
4357        })
4358      }
4359      Row({space: 2}) {
4360        Button("获取选中内容").onClick(() => {
4361          // 获取选中范围
4362          let richEditorSelection = this.controller.getSelection();
4363          let start = richEditorSelection.start ? richEditorSelection.start : 0;
4364          let end = richEditorSelection.end ? richEditorSelection.end : 0;
4365          // 获取组件展示的属性字符串
4366          this.richEditorStyledString = this.controller.getStyledString();
4367          this.selection = '[ ' + start + ' , ' + end + ' ]';
4368          if (start == end) {
4369            this.content = "";
4370          } else {
4371            this.content = this.richEditorStyledString.subStyledString(start, end - start).getString();
4372          }
4373        })
4374        Button("更新选中样式").onClick(() => {
4375          // 获取选中范围
4376          let richEditorSelection = this.controller.getSelection();
4377          let start = richEditorSelection.start ? richEditorSelection.start : 0;
4378          let end = richEditorSelection.end ? richEditorSelection.end : 0;
4379          // 获取组件展示的属性字符串
4380          this.richEditorStyledString = this.controller.getStyledString();
4381          this.richEditorStyledString.setStyle({
4382            start: start,
4383            length: end - start,
4384            styledKey: StyledStringKey.FONT,
4385            styledValue: this.textStyle
4386          })
4387          // 使变更样式后的属性字符串展示在组件上
4388          this.controller.setStyledString(this.richEditorStyledString);
4389        })
4390      }
4391      Row({space: 2}) {
4392        //将属性字符串转换成span信息
4393        Button("调用fromStyledString").onClick(() => {
4394          this.controller1.addTextSpan("调用fromStyledString:" + JSON.stringify(this.controller1.fromStyledString(this.mutableStyledString)))
4395        })
4396        //将给定范围的组件内容转换成属性字符串
4397        Button("调用toStyledString").onClick(() => {
4398          this.controller.setStyledString(this.controller1.toStyledString({
4399            start: 0,
4400            end: 13
4401          }))
4402        })
4403      }
4404    }
4405  }
4406}
4407
4408```
4409
4410![StyledString](figures/StyledString(example20).gif)
4411
4412### 示例21
4413LayoutManager使用示例。
4414
4415```ts
4416@Entry
4417@Component
4418export struct Index {
4419  @State lineCount: string = ""
4420  @State glyphPositionAtCoordinate: string = ""
4421  @State lineMetrics: string = ""
4422  controller: RichEditorController = new RichEditorController();
4423  @State textStr: string =
4424    'Hello World! 你好,世界!'
4425
4426  build() {
4427    Scroll() {
4428      Column() {
4429        Text('RichEditor组件getLayoutManager接口获取相对于组件的布局信息')
4430          .fontSize(9)
4431          .fontColor(0xCCCCCC)
4432          .width('90%')
4433          .padding(10)
4434        RichEditor({ controller: this.controller })
4435          .borderColor(Color.Red)
4436          .borderWidth(1)
4437          .onReady(() => {
4438            this.controller.addTextSpan(this.textStr)
4439          })
4440          .onAreaChange(() => {
4441            let layoutManager = this.controller.getLayoutManager();
4442            this.lineCount = "LineCount: " + layoutManager.getLineCount()
4443          })
4444
4445        Text('LineCount').fontSize(9).fontColor(0xCCCCCC).width('90%').padding(10)
4446        Text(this.lineCount)
4447
4448        Text('GlyphPositionAtCoordinate').fontSize(9).fontColor(0xCCCCCC).width('90%').padding(10)
4449        Button("相对组件坐标[150,50]字形信息")
4450          .onClick(() => {
4451            let layoutManager: LayoutManager = this.controller.getLayoutManager()
4452            let position = layoutManager.getGlyphPositionAtCoordinate(150, 50)
4453            this.glyphPositionAtCoordinate =
4454            "相对组件坐标[150,50] glyphPositionAtCoordinate position: " + position.position + " affinity: " +
4455            position.affinity
4456          })
4457          .margin({ bottom: 20, top: 10 })
4458        Text(this.glyphPositionAtCoordinate)
4459
4460        Text('LineMetrics').fontSize(9).fontColor(0xCCCCCC).width('90%').padding(10)
4461        Button("首行行信息、文本样式信息、以及字体属性信息")
4462          .onClick(() => {
4463            let layoutManager: LayoutManager = this.controller.getLayoutManager()
4464            let lineMetrics = layoutManager.getLineMetrics(0)
4465            this.lineMetrics = "lineMetrics is " + JSON.stringify(lineMetrics) + '\n\n'
4466            let runMetrics = lineMetrics.runMetrics
4467            runMetrics.forEach((value, key) => {
4468              this.lineMetrics += "runMetrics key is " + key + " " + JSON.stringify(value) + "\n\n"
4469            });
4470          })
4471          .margin({ bottom: 20, top: 10 })
4472        Text(this.lineMetrics)
4473      }
4474      .margin({ top: 100, left: 8, right: 8 })
4475    }
4476  }
4477}
4478```
4479
4480![LayoutManager](figures/getLayoutManager.gif)
4481
4482### 示例22
4483
4484editMenuOptions 使用示例,展示设置自定义菜单扩展项的文本内容、图标、回调方法。
4485
4486```ts
4487// xxx.ets
4488@Entry
4489@Component
4490struct RichEditorExample {
4491  controller: RichEditorController = new RichEditorController();
4492  options: RichEditorOptions = { controller: this.controller }
4493
4494  onCreateMenu(menuItems: Array<TextMenuItem>) {
4495    console.log('menuItems size=' + menuItems.length);
4496    menuItems.forEach((value, index) => {
4497      console.log('menuItem' + index + ', id=' + JSON.stringify(value));
4498    })
4499    let extensionMenuItems: Array<TextMenuItem> = [
4500      {
4501        content: 'RichEditor扩展1', icon: $r('app.media.startIcon'), id: TextMenuItemId.of('extension1')
4502      },
4503      {
4504        content: 'RichEditor扩展2', icon: $r('app.media.startIcon'), id: TextMenuItemId.of('extension2')
4505      },
4506      {
4507        content: 'RichEditor扩展3', icon: $r('app.media.startIcon'), id: TextMenuItemId.of('extension3')
4508      },
4509      {
4510        content: 'RichEditor扩展4', icon: $r('app.media.startIcon'), id: TextMenuItemId.of('extension4')
4511      }
4512    ]
4513    return menuItems.concat(extensionMenuItems)
4514  }
4515  onMenuItemClicked(menuItem: TextMenuItem, textRange: TextRange) {
4516    if (menuItem.id.equals(TextMenuItemId.of('extension1'))) {
4517      console.log('click' + menuItem.content + ', textRange=' + JSON.stringify(textRange))
4518      return true;
4519    }
4520    return false;
4521  }
4522
4523  build() {
4524    Row() {
4525      RichEditor(this.options)
4526        .onReady(() => {
4527          this.controller.addTextSpan("RichEditor扩展")
4528        })
4529        .editMenuOptions({
4530          onCreateMenu: (menuItems: Array<TextMenuItem>) => {
4531            return this.onCreateMenu(menuItems)
4532          },
4533          onMenuItemClick: (menuItem: TextMenuItem, textRange: TextRange) => {
4534            return this.onMenuItemClicked(menuItem, textRange)
4535          }
4536        })
4537        .height(200)
4538        .borderWidth(1)
4539        .borderColor(Color.Red)
4540    }
4541  }
4542}
4543```
4544
4545![RichEditorSelectionMenuOptions](figures/richEditorSelectionMenuOptions.png)
4546
4547### 示例23
4548
4549barState、enableKeyboardOnFocus、getPreviewText使用示例。
4550
4551```ts
4552// xxx.ets
4553import { JSON } from '@kit.ArkTS';
4554
4555@Entry
4556@Component
4557struct RichEditor_example {
4558  controller: RichEditorController = new RichEditorController()
4559  options: RichEditorOptions = { controller: this.controller };
4560
4561  controller1: RichEditorController = new RichEditorController()
4562  options1: RichEditorOptions = { controller: this.controller1 };
4563
4564  @State e: boolean = true
4565  @State bs_num: number = 0
4566  @State bs: (BarState | undefined)[] = [BarState.Auto, BarState.On, BarState.Off, undefined]
4567  @State bs_string: (String)[] = ["Auto", "On", "Off", "undefined"]
4568
4569  build() {
4570    Column({space: 3}) {
4571      RichEditor(this.options)
4572        .onReady(() => {
4573          this.controller.addTextSpan('文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本', {
4574            style: {
4575              fontColor: Color.Black,
4576              fontSize: 15
4577            }
4578          })
4579        })
4580        .onDidIMEInput((value: TextRange) => {
4581          this.controller1.addTextSpan("\n" + "触发了onDidIMEInput回调,输入法本次输入内容范围为:(" + value.start + "," + value.end + ")", {
4582            style: {
4583              fontColor: Color.Gray,
4584              fontSize: 10
4585            }
4586          })
4587        })
4588        .onSelectionChange((value: RichEditorRange) => {
4589          this.controller1.addTextSpan("\n" + "触发了onSelectionChange回调,起始范围信息为:(" + value.start + "," + value.end + ")", {
4590            style: {
4591              fontColor: Color.Gray,
4592              fontSize: 10
4593            }
4594          })
4595        })
4596        .width(300)
4597        .height(100)
4598        .margin(20)
4599        .barState(this.bs[this.bs_num])
4600        .enableKeyboardOnFocus(this.e)
4601        .enableHapticFeedback(true)
4602
4603      RichEditor(this.options1).width(300)
4604
4605      Button('设置barState为:' + this.bs_string[this.bs_num])
4606        .height(30)
4607        .fontSize(13)
4608        .onClick(() => {
4609          this.bs_num++
4610          if (this.bs_num > (this.bs.length - 1)) {
4611            this.bs_num = 0
4612          }
4613        })
4614
4615      Button('设置enableKeyboardOnFocus为:' + this.e)
4616        .height(30)
4617        .fontSize(13)
4618        .onClick(() => {
4619          this.e = !this.e
4620        })
4621
4622      Button('获取预上屏信息')
4623        .height(30)
4624        .fontSize(13)
4625        .onClick(() => {
4626          this.controller1.addTextSpan("\n获取预上屏信息:" + JSON.stringify(this.controller.getPreviewText()))
4627        })
4628    }
4629  }
4630}
4631
4632```
4633
4634![StyledString](figures/example23.gif)