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