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