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