富文本(Rich Text) 不仅承载着多样化的内容呈现需求,更是连接用户与服务的关键桥梁。无论是社交应用中的图文混排、教育类 App 的课件展示,还是办公场景的文档编辑,富文本的实现能力直接影响着用户体验的深度与广度。

话不多说,线上效果图:

需要用到:RichEditor这个组件

直接上代码,copy过去就能使用

注意:titlebar自己根据情况去实现,我这里注释了,插入图片自己根据业务去实现,我这里本地没有接口去使用

// import { TitleBar } from '../components/TitleBar';
// import { Title } from '../components/Title';

@Extend(Column) function cardStyle() {
  .backgroundColor(Color.White)
  .borderRadius(24)
  .width('100%')
  .padding(5)
}

@Entry
@Component
struct RichEditorSample {
  @State setStyle: Boolean = false;
  @State setStyle1: Boolean = false;
  @State setStyle2: Boolean = false;
  @State setStyle3: Boolean = false;
  @State setStyle4: Boolean = false;
  @State setStyle5: Boolean = false;
  @State setStyle6: Boolean = false;
  @State styleDialog: Visibility = Visibility.None;
  @State fontWeightSet: FontWeight = FontWeight.Normal;
  @State fontStyleSet: FontStyle = FontStyle.Normal;
  @State fontDecorationSet: TextDecorationType = TextDecorationType.None;
  @State fontAlignLeftSet: TextAlign = TextAlign.Start;
  @State fontAlignMiddleSet: TextAlign = TextAlign.Center;
  @State fontAlignRightSet: TextAlign = TextAlign.End;
  @State tipsValue: number = 32;
  private start: number = -1;
  private end: number = -1;
  private fontColors: string[] = ["#FA2A2D","#FFBF00","#41BA41","#00AAEE","#3F56EA","#8A2BE2","#000000"];

  controller: RichEditorController = new RichEditorController();

  updateVisible(){
    this.setStyle = !this.setStyle;
    if(this.setStyle){
      this.styleDialog = Visibility.Visible;
    }else{
      this.styleDialog = Visibility.None;
    }
  }

  updateFontWeight(){
    this.setStyle1 = !this.setStyle1;
    if(this.setStyle1){
      this.fontWeightSet = FontWeight.Bolder;
    }else{
      this.fontWeightSet = FontWeight.Normal;
    }
  }

  updateFontStyle(){
    this.setStyle2 = !this.setStyle2;
    if(this.setStyle2){
      this.fontStyleSet = FontStyle.Italic;
    }else{
      this.fontStyleSet = FontStyle.Normal;
    }
  }

  updateFontDecoration(){
    this.setStyle3 = !this.setStyle3;
    if(this.setStyle3){
      this.fontDecorationSet = TextDecorationType.Underline;
    }else{
      this.fontDecorationSet = TextDecorationType.None;
    }
  }

  updateFontAlignLeft(){
    this.setStyle4 = !this.setStyle4;
    if(this.setStyle4){
      this.fontAlignLeftSet = TextAlign.Start;
    }else{
      this.fontAlignLeftSet = TextAlign.JUSTIFY;
    }
  }

  updateFontAlignMiddle(){
    this.setStyle5 = !this.setStyle5;
    if(this.setStyle5){
      this.fontAlignMiddleSet = TextAlign.Center;
    }else{
      this.fontAlignMiddleSet = TextAlign.JUSTIFY;
    }
  }

  updateFontAlignRight(){
    this.setStyle6 = !this.setStyle6;
    if(this.setStyle6){
      this.fontAlignRightSet = TextAlign.End;
    }else{
      this.fontAlignRightSet = TextAlign.JUSTIFY;
    }
  }

  build() {
    Column() {
      // TitleBar({ title: $r('app.string.rich_editor_title') })
      Scroll() {
        Column() {
          RichEditor({ controller: this.controller })
            .onReady(() => {
              this.controller.addTextSpan("Hello World。\n" +
                "Familiar images automatically give people a sense of calm and nostalgia. " +
                "Early web designers liked the elements of the 1980s, but today, the aesthetics of the 1990s.\n",
                {
                  style:
                  {
                    fontColor: Color.Black,
                    fontSize: 16
                  }
                })
              // this.controller.addImageSpan($rawfile('richEditor/operate.svg'),
              //   {
              //     imageStyle:
              //     {
              //       size: ["100px", "54px"]
              //     }
              //   })
            })
            .onSelect((value: RichEditorSelection) => {
              this.start = value.selection[0];
              this.end = value.selection[1];
            })
            .height("50%")
            .width("100%")
          Stack() {
            Column() {
              Row() {
                Text($r('app.string.rich_editor_style'))
                  .fontSize(14)
                  .padding({top:5})
                Image($rawfile('richEditor/close.svg'))
                  .width(25)
                  .height(25)
                  .onClick(() => {
                    this.styleDialog = Visibility.None
                  })
              }.height(25)
              .margin({bottom:10})

              Row({ space: 38 }) {
                Image($rawfile('richEditor/Normal.svg'))
                  .width(15)
                  .height(15)
                  .onClick(() => {
                    this.updateFontWeight()
                    if(this.end!=this.start){
                      this.controller.updateSpanStyle({
                        start: this.start,
                        end: this.end,
                        textStyle:
                        {
                          fontWeight: this.fontWeightSet
                        }
                      })
                    }
                  })
                Image($rawfile('richEditor/incline.svg'))
                  .width(15)
                  .height(15)
                  .onClick(() => {
                    this.updateFontStyle()
                    if(this.end!=this.start) {
                      this.controller.updateSpanStyle({
                        start: this.start,
                        end: this.end,
                        textStyle:
                        {
                          fontStyle: this.fontStyleSet
                        }
                      })
                    }
                  })
                Image($rawfile('richEditor/underline.svg'))
                  .width(15)
                  .height(15)
                  .onClick(() => {
                    this.updateFontDecoration()
                    if(this.end!=this.start) {
                      this.controller.updateSpanStyle({
                        start: this.start,
                        end: this.end,
                        textStyle:
                        {
                          decoration: {
                            type: this.fontDecorationSet
                          }
                        }
                      })
                    }
                  })
                Image($rawfile('richEditor/left.svg'))
                  .width(15)
                  .height(15)
                  .onClick(() => {
                    this.updateFontAlignLeft()
                    if(this.end!=this.start) {
                      this.controller.updateParagraphStyle({
                        start: this.start,
                        end: this.end,
                        style:
                        {
                          textAlign:this.fontAlignLeftSet
                        }
                      })
                    }
                  })
                Image($rawfile('richEditor/align.svg'))
                  .width(15)
                  .height(15)
                  .onClick(() => {
                    this.updateFontAlignMiddle()
                    if(this.end!=this.start) {
                      this.controller.updateParagraphStyle({
                        start: this.start,
                        end: this.end,
                        style:
                        {
                          textAlign:this.fontAlignMiddleSet
                        }
                      })
                    }
                  })
                Image($rawfile('richEditor/right.svg'))
                  .width(15)
                  .height(15)
                  .onClick(() => {
                    this.updateFontAlignRight()
                    if(this.end!=this.start) {
                      this.controller.updateParagraphStyle({
                        start: this.start,
                        end: this.end,
                        style:
                        {
                          textAlign:this.fontAlignRightSet
                        }
                      })
                    }
                  })
              }
              .height(25)
              .margin({bottom:10})

              Row() {
                ForEach(this.fontColors,(item: string) => {
                  Circle({ width: 15, height: 15 }).fill(item)
                    .onClick(() => {
                      if(this.end!=this.start){
                        this.controller.updateSpanStyle({
                          start: this.start,
                          end: this.end,
                          textStyle:
                          {
                            fontColor: item
                          }
                        })
                      }
                    })
                })
              }.height(25)
              .width('100%')
              .margin({bottom:10})
              .justifyContent(FlexAlign.SpaceBetween)

              Row() {
                Text("Aa")
                  .width(20)
                  .height(24)
                  .fontSize(11)
                  .fontWeight(400)
                  .onClick(() => {
                    this.tipsValue = this.tipsValue - 2
                    if(this.end!=this.start){
                      this.controller.updateSpanStyle({
                        start: this.start,
                        end: this.end,
                        textStyle:
                        {
                          fontSize: this.tipsValue/2
                        }
                      })
                    }
                  })
                Slider({ style: SliderStyle.InSet, value: this.tipsValue })
                  .width(210)
                  .showTips(true, 'Size:' + this.tipsValue.toFixed())
                  .onChange(value => {
                    this.tipsValue = value
                    if(this.end!=this.start){
                      this.controller.updateSpanStyle({
                        start: this.start,
                        end: this.end,
                        textStyle:
                        {
                          fontSize: this.tipsValue/2
                        }
                      })
                    }
                  })
                Text("Aa")
                  .width(20)
                  .height(24)
                  .fontSize(17)
                  .fontWeight(400)
                  .onClick(() => {
                    this.tipsValue = this.tipsValue + 2
                    if(this.end!=this.start){
                      this.controller.updateSpanStyle({
                        start: this.start,
                        end: this.end,
                        textStyle:
                        {
                          fontSize: this.tipsValue/2
                        }
                      })
                    }
                  })
              }.height(25).margin({bottom:60})
              .width('100%')
              .justifyContent(FlexAlign.SpaceBetween)

            }.visibility(this.styleDialog)
            .width("100%")
            .height("85%")
            .margin({bottom:"85%"})
            .padding(10)
            .zIndex(1)
            .border({
              radius: { topLeft: 15, topRight: 15 },
            })
            .backgroundColor($r('app.color.background_light_gray'))

            Row({ space: 150 }) {
              Image($rawfile('richEditor/font-normal.svg'))
                .width(40)
                .height(40)
                .onClick(() => {
                  this.updateVisible()
                })
              Image($rawfile('richEditor/addPhoto.svg'))
                .width(35)
                .height(35)
                .onClick(() => {
                  //插入图片
                  this.controller.addImageSpan($rawfile('home/poster4.png'),
                    {
                      imageStyle:
                      {
                        size: ["200px", "200px"]
                      }
                    })
                })
            }
            .padding({top:"50%"})
            .justifyContent(FlexAlign.Center)
            .width("100%")
            .height("15%")
            .zIndex(3)
          }.height("30%")
        }
        .alignItems(HorizontalAlign.Start)
        .cardStyle()
        .constraintSize({ minHeight: '100%' })
      }
      .width('95%')
      .height('80%')
      .backgroundColor($r('app.color.divider_block_color'))
      Row(){
        Button('提交').width('80%')
      }
    }.height('100%')
    .width('100%')
    .backgroundColor($r('app.color.divider_block_color'))
    .padding({ left: 10, right: 10 })

  }
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐