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