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