1# 富文本(RichEditor) 2RichEditor是支持图文混排和文本交互式编辑的组件,通常用于响应用户的对于图文混合内容的输入操作,例如可以输入图片的评论区。具体用法参考[RichEditor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md)。 3 4## 创建RichEditor组件 5RichEditor通过调用接口来创建,可以创建以下两种类型: 6 7### 创建不使用属性字符串构建的RichEditor组件 8```ts 9RichEditor(value: RichEditorOptions) 10``` 11其中RichEditorOptions是富文本组件初始化选项。 12 13```ts 14controller: RichEditorController = new RichEditorController(); 15options: RichEditorOptions = { controller: this.controller }; 16 17RichEditor(this.options) 18 .onReady(() => { 19 this.controller.addTextSpan('创建不使用属性字符串构建的RichEditor组件。', { 20 style: { 21 fontColor: Color.Black, 22 fontSize: 15 23 } 24 }) 25 }) 26``` 27 28 29### 创建使用属性字符串构建的RichEditor组件 30```ts 31RichEditor(options: RichEditorStyledStringOptions) 32``` 33 34其中RichEditorStyledStringOptions是富文本组件初始化选项。属性字符串的使用方法请参考[属性字符串(StyledString/MutableStyledString)](arkts-styled-string.md)。 35 36```ts 37mutableStyledString: MutableStyledString = new MutableStyledString("创建使用属性字符串构建的RichEditor组件。", 38 [{ 39 start: 0, 40 length: 5, 41 styledKey: StyledStringKey.FONT, 42 styledValue: this.fontStyle 43 }]); 44 45controller: RichEditorStyledStringController = new RichEditorStyledStringController(); 46options: RichEditorStyledStringOptions = {controller: this.controller}; 47 48RichEditor(this.options) 49 .onReady(() => { 50 this.controller.setStyledString(this.mutableStyledString); 51 }) 52``` 53 54 55## 设置属性 56 57### 设置自定义选择菜单 58 59通过[bindSelectionMenu](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#bindselectionmenu)设置自定义选择菜单。 60 61其中spanType是菜单的类型,默认值为文字类型;content是菜单的内容;responseType是菜单的响应类型,默认类型为长按;options是菜单的选项,可设置自定义选择菜单弹出或关闭时的回调。 62 63自定义菜单超长时,建议内部嵌套Scroll组件使用,避免键盘被遮挡。 64 65```ts 66RichEditor(this.options) 67 .onReady(() => { 68 this.controller.addTextSpan('组件设置了自定义菜单,长按可触发。', { 69 style: { 70 fontColor: Color.Black, 71 fontSize: 18 72 } 73 }) 74 }) 75 .bindSelectionMenu(RichEditorSpanType.TEXT, this.SystemMenu, ResponseType.LongPress, { 76 onDisappear: () => { 77 this.sliderShow = false 78 } 79 }) 80 .width(300) 81 .height(300) 82 83@Builder 84SystemMenu() { 85 Column() { 86 Menu() { 87 if (this.controller) { 88 MenuItemGroup() { 89 MenuItem({ 90 startIcon: this.theme.cutIcon, 91 content: "剪切", 92 labelInfo: "Ctrl+X", 93 }) 94 MenuItem({ 95 startIcon: this.theme.copyIcon, 96 content: "复制", 97 labelInfo: "Ctrl+C" 98 }) 99 MenuItem({ 100 startIcon: this.theme.pasteIcon, 101 content: "粘贴", 102 labelInfo: "Ctrl+V" 103 }) 104 } 105 } 106 } 107 .radius(this.theme.containerBorderRadius) 108 .clip(true) 109 .backgroundColor(Color.White) 110 .width(this.theme.defaultMenuWidth) 111 } 112 .width(this.theme.defaultMenuWidth) 113} 114``` 115 116 117 118### 设置输入框光标、手柄颜色 119 120通过[caretColor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#caretcolor12)设置输入框光标、手柄颜色。 121 122```ts 123RichEditor(this.options) 124 .onReady(() => { 125 this.controller.addTextSpan('组件设置了光标手柄颜色。', { 126 style: { 127 fontColor: Color.Black, 128 fontSize: 15 129 } 130 }) 131 }) 132 .caretColor(Color.Orange) 133 .width(300) 134 .height(300) 135``` 136 137 138 139### 设置无输入时的提示文本 140 141通过[placeholder](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#placeholder12)设置无输入时的提示文本。 142 143其中value为无输入时的提示文本;style为添加提示文本的字体样式,style缺省时默认跟随主题。 144 145```ts 146RichEditor(this.options) 147 .placeholder("此处为提示文本...", { 148 fontColor: Color.Gray, 149 font: { 150 size: 15, 151 weight: FontWeight.Normal, 152 family: "HarmonyOS Sans", 153 style: FontStyle.Normal 154 } 155 }) 156 .width(300) 157 .height(300) 158``` 159 160 161 162更多属性使用请参考[RichEditor属性](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#属性)。 163 164## 添加事件 165### 添加组件初始化完成后可触发的回调 166 167通过[onReady](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onready)来添加组件初始化完成后可触发的回调。 168 169其中callback是订阅富文本组件初始化完成的回调。 170 171```ts 172RichEditor(this.options) 173 .onReady(() => { 174 this.controller.addTextSpan('onReady回调内容是组件内预置文本。', { 175 style: { 176 fontColor: Color.Black, 177 fontSize: 15 178 } 179 }) 180 }) 181``` 182 183 184 185### 添加组件内容被选中时可触发的回调 186 187通过[onSelect](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onselect)来添加组件内容被选中时可触发的回调。 188 189在callback中,[RichEditorSelection](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorselection)为选中的所有内容信息。 190 191触发该回调有两种方式:可通过鼠标左键按下选择,松开左键后触发回调,也可通过手指选择,松开手指触发回调。 192 193```ts 194RichEditor(this.options) 195 .onReady(() => { 196 this.controller.addTextSpan('选中此处文本,触发onselect回调。', { 197 style: { 198 fontColor: Color.Black, 199 fontSize: 15 200 } 201 }) 202 }) 203 .onSelect((value: RichEditorSelection) => { 204 this.controller1.addTextSpan(JSON.stringify(value), { 205 style: { 206 fontColor: Color.Gray, 207 fontSize: 10 208 } 209 }) 210 }) 211 .width(300) 212 .height(50) 213Text('查看回调内容:').fontSize(10).fontColor(Color.Gray).width(300) 214RichEditor(this.options1) 215 .width(300) 216 .height(70) 217``` 218 219 220 221### 添加图文变化前和图文变化后可触发的回调 222 223通过[onWillChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onwillchange12)添加图文变化前可触发的回调。通过[onDidChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#ondidchange12)添加图文变化后可触发的回调。 224 225onWillChange的callback中:[RichEditorChangeValue](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorchangevalue12)为图文变化信息;boolean为true时,表示当前图文允许被更改。boolean为false时,表示当前图文不允许被更改。 226 227onDidChange的callback中:[OnDidChangeCallback](../reference/apis-arkui/arkui-ts/ts-text-common.md#ondidchangecallback12)为图文变化前后的内容范围。 228 229使用[RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12)构建的RichEditor组件不支持这两种回调。 230 231```ts 232RichEditor(this.options) 233 .onReady(() => { 234 this.controller.addTextSpan('组件内图文变化前,触发回调。\n图文变化后,触发回调。', { 235 style: { 236 fontColor: Color.Black, 237 fontSize: 15 238 } 239 }) 240 }) 241 .onWillChange((value: RichEditorChangeValue) => { 242 this.controller1.addTextSpan('组件内图文变化前,触发回调:\n' + JSON.stringify(value), { 243 style: { 244 fontColor: Color.Gray, 245 fontSize: 10 246 } 247 }) 248 return true; 249 }) 250 .onDidChange((rangeBefore: TextRange, rangeAfter: TextRange) => { 251 this.controller1.addTextSpan('\n图文变化后,触发回调:\nrangeBefore:' + JSON.stringify(rangeBefore) + '\nrangeAfter:' + JSON.stringify(rangeBefore), { 252 style: { 253 fontColor: Color.Gray, 254 fontSize: 10 255 } 256 }) 257 return true; 258 }) 259 .width(300) 260 .height(50) 261Text('查看回调内容:').fontSize(10).fontColor(Color.Gray).width(300) 262RichEditor(this.options1) 263 .width(300) 264 .height(70) 265``` 266 267 268 269### 添加输入法输入内容前和完成输入后可触发的回调 270 271通过[aboutToIMEInput](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#abouttoimeinput)添加输入法输入内容前可触发的回调。通过[onIMEInputComplete](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onimeinputcomplete)添加输入法完成输入后可触发的回调。 272 273aboutToIMEInput的callback中:[RichEditorInsertValue](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorinsertvalue)为输入法将要输入内容信息;boolean为true时,组件执行添加内容操作。boolean为false时,组件不执行添加内容操作。 274 275onIMEInputComplete的callback中:[RichEditorTextSpanResult](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditortextspanresult)为输入法完成输入后的文本Span信息。 276 277使用[RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12)构建的RichEditor组件不支持这两种回调。 278 279```ts 280RichEditor(this.options) 281 .onReady(() => { 282 this.controller.addTextSpan('输入法输入内容前,触发回调。\n输入法完成输入后,触发回调。' , { 283 style: { 284 fontColor: Color.Black, 285 fontSize: 15 286 } 287 }) 288 }) 289 .aboutToIMEInput((value: RichEditorInsertValue) => { 290 this.controller1.addTextSpan('输入法输入内容前,触发回调:\n'+JSON.stringify(value), { 291 style: { 292 fontColor: Color.Gray, 293 fontSize: 10 294 } 295 }) 296 return true; 297 }) 298 .onIMEInputComplete((value: RichEditorTextSpanResult) => { 299 this.controller1.addTextSpan('输入法完成输入后,触发回调:\n'+ JSON.stringify(value), { 300 style: { 301 fontColor: Color.Gray, 302 fontSize: 10 303 } 304 }) 305 return true; 306 }) 307 .width(300) 308 .height(50) 309Text('查看回调内容:').fontSize(10).fontColor(Color.Gray).width(300) 310RichEditor(this.options1) 311 .width(300) 312 .height(70) 313``` 314 315 316 317### 添加完成粘贴前可触发的回调 318 319通过[onPaste](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onpaste11)添加完成粘贴前可触发的回调。 320 321其中callback用于定义用户粘贴事件。 322 323由于系统的默认粘贴,只支持纯文本的粘贴。所以开发者可以通过该方法,覆盖系统默认行为,实现图文的粘贴。 324 325```ts 326RichEditor(this.options) 327 .onReady(() => { 328 this.controller.addTextSpan('对此处文本进行复制粘贴操作可触发对应回调。', { 329 style: { 330 fontColor: Color.Black, 331 fontSize: 15 332 } 333 }) 334 }) 335 .onPaste(() => { 336 this.controller1.addTextSpan('触发onPaste回调\n', { 337 style: { 338 fontColor: Color.Gray, 339 fontSize: 10 340 } 341 }) 342 }) 343 .width(300) 344 .height(70) 345``` 346 347### 添加完成剪切前可触发的回调 348 349通过[onCut](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#oncut12)添加完成剪切前可触发的回调。 350 351其中callback用于定义用户剪切事件。 352 353由于系统的默认剪切行为,只支持纯文本的剪切。所以开发者可以通过该方法,覆盖系统默认行为,实现图文的剪切。 354 355```ts 356RichEditor(this.options) 357 .onReady(() => { 358 this.controller.addTextSpan('对此处文本进行复制粘贴操作可触发对应回调。', { 359 style: { 360 fontColor: Color.Black, 361 fontSize: 15 362 } 363 }) 364 }) 365 .onCut(() => { 366 this.controller1.addTextSpan('触发onCut回调\n', { 367 style: { 368 fontColor: Color.Gray, 369 fontSize: 10 370 } 371 }) 372 }) 373 .width(300) 374 .height(70) 375``` 376 377### 添加完成复制前可触发的回调 378 379通过[onCopy](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#oncopy12)添加完成复制前可触发的回调。 380 381其中callback用于定义用户复制事件。 382 383由于系统的默认复制行为,只支持纯文本的复制。所以开发者可以通过该方法,覆盖系统默认行为,实现图文的复制。 384 385```ts 386RichEditor(this.options) 387 .onReady(() => { 388 this.controller.addTextSpan('对此处文本进行复制粘贴操作可触发对应回调。', { 389 style: { 390 fontColor: Color.Black, 391 fontSize: 15 392 } 393 }) 394 }) 395 .onCopy(() => { 396 this.controller1.addTextSpan('触发onCopy回调\n', { 397 style: { 398 fontColor: Color.Gray, 399 fontSize: 10 400 } 401 }) 402 }) 403 .width(300) 404 .height(70) 405``` 406 407 408 409 410更多事件使用请参考[RichEditor事件](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#事件)。 411 412## 设置用户预设的样式 413 414通过[setTypingStyle](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#settypingstyle11)设置用户预设的样式。 415 416其中value是预设样式。 417 418```ts 419RichEditor(this.options) 420 .onReady(() => { 421 this.controller.addTextSpan('点击按钮,改变组件预设样式。', { 422 style: { 423 fontColor: Color.Black, 424 fontSize: 15 425 } 426 }) 427 }) 428 .width(300) 429 .height(60) 430Button('setTypingStyle', { 431 buttonStyle: ButtonStyleMode.NORMAL 432 }) 433 .height(30) 434 .fontSize(13) 435 .onClick(() => { 436 this.controller.setTypingStyle({ 437 fontWeight: 'medium', 438 fontColor: Color.Pink, 439 fontSize: 15, 440 fontStyle: FontStyle.Italic, 441 decoration: { 442 type: TextDecorationType.Underline, 443 color: Color.Gray 444 } 445 }) 446 }) 447``` 448 449 450 451## 设置组件内的内容选中时部分背板高亮 452 453通过[setSelection](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#setselection11)设置组件内的内容选中时部分背板高亮。 454 455其中selectionStart为选中开始位置,selectionEnd选中结束位置。当selectionStart和selectionEnd均为-1时表示全选。 456 457当组件内未获焦出现光标时,调用该接口不产生选中效果。 458 459```ts 460RichEditor(this.options) 461 .onReady(() => { 462 this.controller.addTextSpan('点击按钮在此处选中0-2位置的文本。', { 463 style: { 464 fontColor: Color.Black, 465 fontSize: 15 466 } 467 }) 468 }) 469 .width(300) 470 .height(60) 471Button('setSelection(0,2)', { 472 buttonStyle: ButtonStyleMode.NORMAL 473 }) 474 .height(30) 475 .fontSize(13) 476 .onClick(() => { 477 this.controller.setSelection(0, 2) 478 }) 479``` 480 481 482 483## 添加文本内容 484 485除了直接在组件内输入内容,也可以通过[addTextSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addtextspan)添加文本内容。 486 487其中value是文本内容;options是文本选项,用于添加文本的偏移位置和文本样式信息([RichEditorTextSpanOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditortextspanoptions))。 488 489如果组件光标闪烁,插入后光标位置更新为新插入文本的后面。 490 491```ts 492RichEditor(this.options) 493 .onReady(() => { 494 this.controller.addTextSpan('点击按钮在此处添加text。', { 495 style: { 496 fontColor: Color.Black, 497 fontSize: 15 498 } 499 }) 500 }) 501 .width(300) 502 .height(100) 503Button('addTextSpan', { 504 buttonStyle: ButtonStyleMode.NORMAL 505 }) 506 .height(30) 507 .fontSize(13) 508 .onClick(() => { 509 this.controller.addTextSpan('新添加一段文字。') 510 }) 511``` 512 513 514 515## 添加图片内容 516 517通过[addImageSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addimagespan)添加图片内容。 518 519其中value是图片内容;options是图片选项,用于添加图片的偏移位置和图片样式信息([RichEditorImageSpanOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorimagespanoptions))。 520 521添加图片内容,如果组件光标闪烁,插入后光标位置更新为新插入图片的后面。 522 523```ts 524RichEditor(this.options) 525 .onReady(() => { 526 this.controller.addTextSpan('点击按钮在此处添加image。', { 527 style: { 528 fontColor: Color.Black, 529 fontSize: 15 530 } 531 }) 532 }) 533 .width(300) 534 .height(100) 535Button('addImageSpan', { 536 buttonStyle: ButtonStyleMode.NORMAL 537 }) 538 .height(30) 539 .fontSize(13) 540 .onClick(() => { 541 this.controller.addImageSpan($r("app.media.startIcon"), { 542 imageStyle: { 543 size: ["57px", "57px"] 544 } 545 }) 546 }) 547``` 548 549 550 551## 添加@Builder装饰器修饰的内容 552通过[addBuilderSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addbuilderspan11)添加@Builder装饰器修饰的内容。 553 554其中value是builder内容;options是builder选项,可通过[RichEditorBuilderSpanOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorbuilderspanoptions11)设置此builder在RichEditor中的index(一个文字为一个单位)。 555 556```ts 557@Builder 558TextBuilder() { 559 Row() { 560 Image($r('app.media.startIcon')).width(50).height(50).margin(16) 561 Column() { 562 Text("文本文档.txt").fontWeight(FontWeight.Bold).fontSize(16) 563 Text("123.45KB").fontColor('#8a8a8a').fontSize(12) 564 }.alignItems(HorizontalAlign.Start) 565 }.backgroundColor('#f4f4f4') 566 .borderRadius("20") 567 .width(220) 568} 569 570Button('addBuilderSpan', { 571 buttonStyle: ButtonStyleMode.NORMAL 572 }) 573 .height(30) 574 .fontSize(13) 575 .onClick(() => { 576 this.my_builder = () => { 577 this.TextBuilder() 578 } 579 this.controller.addBuilderSpan(this.my_builder) 580 }) 581``` 582 583 584## 添加SymbolSpan内容 585 586可通过[addSymbolSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addsymbolspan11)添加SymbolSpan内容。 587 588其中value是SymbolSpan组件内容;options是SymbolSpan组件选项,用于添加SymbolSpan组件的偏移位置和SymbolSpan组件样式信息( [RichEditorSymbolSpanOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorsymbolspanoptions11) )。 589 590添加SymbolSpan内容,如果组件光标闪烁,插入后光标位置更新为新插入Symbol的后面。 591 592SymbolSpan内容暂不支持手势、复制、拖拽处理。 593 594```ts 595RichEditor(this.options) 596 .onReady(() => { 597 this.controller.addTextSpan('点击按钮在此处添加symbol。', { 598 style: { 599 fontColor: Color.Black, 600 fontSize: 15 601 } 602 }) 603 }) 604 .width(300) 605 .height(100) 606Button('addSymbolSpan', { 607 buttonStyle: ButtonStyleMode.NORMAL 608 }) 609 .height(30) 610 .fontSize(13) 611 .onClick(() => { 612 this.controller.addSymbolSpan($r("sys.symbol.basketball_fill"), { 613 style: { 614 fontSize: 30 615 } 616 }) 617 }) 618``` 619 620 621## 获取组件内span信息 622 623可通过[getSpans](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#getspans)获取组件内span信息。 624 625其中value是需要获取span范围。返回值为Array<[RichEditorTextSpanResult](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditortextspanresult) | [RichEditorImageSpanResult](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorimagespanresult)>,是文本和图片Span信息。 626 627```ts 628RichEditor(this.options) 629 .onReady(() => { 630 this.controller.addTextSpan('点击按钮获取此处span信息。', { 631 style: { 632 fontColor: Color.Black, 633 fontSize: 15 634 } 635 }) 636 }) 637 .width(300) 638 .height(50) 639Text('查看getSpans返回值:').fontSize(10).fontColor(Color.Gray).width(300) 640RichEditor(this.options1) 641 .width(300) 642 .height(50) 643Button('getSpans', { 644 buttonStyle: ButtonStyleMode.NORMAL 645 }) 646 .height(30) 647 .fontSize(13) 648 .onClick(() => { 649 this.controller1.addTextSpan(JSON.stringify(this.controller.getSpans()), { 650 style: { 651 fontColor: Color.Gray, 652 fontSize: 10 653 } 654 }) 655 656 }) 657``` 658 659<!--RP1--><!--RP1End-->