自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我們一起聊聊鴻蒙富文本實踐

系統(tǒng) 其他OS
想要實現(xiàn)表情圖片自動匹配,首先就需要先有表情圖片,要有對應(yīng)的表情配置表,項目中的表情配置分程序內(nèi)置默認(rèn)配置與線上后臺下發(fā)配置。

1.鴻蒙中的文本展示-Text組件

Text 組件的普通用法和其他語言一樣,可以直接使用字符串Text('我是一段文本')

通過點語法設(shè)置文本樣式:

Text('我是超長文本,超出的部分顯示省略號。I am an extra long text, with ellipses displayed for any excess。')
  .width(250)
  .textOverflow({ overflow: TextOverflow.Ellipsis })
  .maxLines(1)
  .fontSize(12)
  .border({ width: 1 })
  .padding(10)

也可以將 Text 組件作為容器,添加 SpanImageSpan,針對每段文本設(shè)置不同的樣式并且統(tǒng)一換行,ImageSpan 可以展示本地圖片與網(wǎng)絡(luò)圖片:

Text() {
  Span('我是Span1,').fontSize(16).fontColor(Color.Grey)
    .decoration({ type: TextDecorationType.LineThrough, color: Color.Red })
  Span('我是Span2').fontColor(Color.Blue).fontSize(16)
    .fontStyle(FontStyle.Italic)
    .decoration({ type: TextDecorationType.Underline, color: Color.Black })
  Span(',我是Span3').fontSize(16).fontColor(Color.Grey)
    .decoration({ type: TextDecorationType.Overline, color: Color.Green })
}
.borderWidth(1)
.padding(10)

圖片圖片

// xxx.ets
@Entry
@Component
struct SpanExample {
  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Text() {
        Span('This is the Span and ImageSpan component').fontSize(25).textCase(TextCase.Normal)
          .decoration({ type: TextDecorationType.None, color: Color.Pink })
      }.width('100%').textAlign(TextAlign.Center)

      Text() {
        ImageSpan($r('app.media.icon'))
          .width('200px')
          .height('200px')
          .objectFit(ImageFit.Fill)
          .verticalAlign(ImageSpanAlignment.CENTER)
        Span('I am LineThrough-span')
          .decoration({ type: TextDecorationType.LineThrough, color: Color.Red }).fontSize(25)
        ImageSpan($r('app.media.icon'))
          .width('50px')
          .height('50px')
          .verticalAlign(ImageSpanAlignment.TOP)
        Span('I am Underline-span')
          .decoration({ type: TextDecorationType.Underline, color: Color.Red }).fontSize(25)
        ImageSpan($r('app.media.icon'))
          .size({ width: '100px', height: '100px' })
          .verticalAlign(ImageSpanAlignment.BASELINE)
        Span('I am Underline-span')
          .decoration({ type: TextDecorationType.Underline, color: Color.Red }).fontSize(25)
        ImageSpan($r('app.media.icon'))
          .width('70px')
          .height('70px')
          .verticalAlign(ImageSpanAlignment.BOTTOM)
        Span('I am Underline-span')
          .decoration({ type: TextDecorationType.Underline, color: Color.Red }).fontSize(50)
      }
      .width('100%')
      .textIndent(50)
    }.width('100%').height('100%').padding({ left: 0, right: 0, top: 0 })
  }
}

圖片圖片

這樣通過 Span、ImageSpan 混排就實現(xiàn)了基礎(chǔ)的圖文混排。

2.表情圖片自動匹配

對于實際中的實操,往往不是固定寫好的混排代碼,而是需要針對后端下發(fā)的數(shù)據(jù)自動進(jìn)行轉(zhuǎn)譯。比如帶表情的文本。

項目中的自定義表情一般會以配置表的形式進(jìn)行管理:

{"imageName":"icon_emotion_1","description":"[微笑]","id":44},{"imageName":"icon_emotion_2","description":"[嘻嘻]","id":43}

用特殊格式的字符串,如:"[微笑]"、"[嘻嘻]",來分別對應(yīng)相應(yīng)的表情圖片。

而后端下發(fā)的數(shù)據(jù)則只是一段包含表情關(guān)鍵字的普通文本,并且沒有額外下發(fā)表情文本的位置信息,如:"第一次見面她幫他出頭,他被她拽拽的氣質(zhì)吸引,對她一見鐘情,多年后重逢續(xù)寫故事[色]這該死的羈絆~",轉(zhuǎn)換后為:

圖片圖片

這樣就需要將文本切塊,把本文中的表情關(guān)鍵字提取出來。上面的文本就轉(zhuǎn)換為:"第一次見面她幫他出頭,他被她拽拽的氣質(zhì)吸引,對她一見鐘情,多年后重逢續(xù)寫故事"、"[色]"、"這該死的羈絆~"。切塊的過程采用正則匹配方式。

首先,需要將表情配置表中的所有關(guān)鍵字整合加工為正則匹配字符串:"[微笑]|[嘻嘻]|[哭笑]...",這樣只要目標(biāo)文本中包含任意一個關(guān)鍵字,都可以獲得匹配結(jié)果。在加工正則字符串的過程中,同時將表情關(guān)鍵字與圖片名組裝為鍵值對表:["[微笑]":"icon_emotion_1","[嘻嘻]":"icon_emotion_2",...],用以后續(xù)獲取轉(zhuǎn)譯圖片。

鴻蒙中的正則匹配代碼:

let reg = RegExp(EmoticonManager.getInstance().emojiRegExpStr,'g') //正則匹配串
let result: IterableIterator<RegExpMatchArray> = content.matchAll(reg)//可迭代匹配結(jié)果
let next = result.next()//第一個結(jié)果
while (next.done == false) {
 let matchArr: RegExpMatchArray = next.value
  
  //分割字符串
  
 next = result.next() //下一個結(jié)果
}

注意項:RegExp(xxx,'g') ,'g' 代表貪婪模式,會返回所有匹配結(jié)果,不然只會獲取第一個匹配結(jié)果。

最終將文本 "第一次見面她幫他出頭,他被她拽拽的氣質(zhì)吸引,對她一見鐘情,多年后重逢續(xù)寫故事[色]這該死的羈絆~" 轉(zhuǎn)換為數(shù)據(jù)模型數(shù)組:

[
 [
  content: "第一次見面她幫他出頭,他被她拽拽的氣質(zhì)吸引,對她一見鐘情,多年后重逢續(xù)寫故事",
  type: Text,
  resource: NULL
 ],
 [
  content: "[色]",
  type: Emoji,
  resource: xxxx
 ],
 [
  content: "這該死的羈絆~",
  type: Text,
  resource: NULL
 ]
]

再在 Text 組件中遍歷組裝:

Text(){
 ForEach(this.model.getDecodedContentArr(), (element: CommentTextModel) => {
  if (element.type == CommentTextType.Text) {
      Span(element.content)
        .onClick(() => {
         this.openCommentInput()
       })
    }
    if (element.type == CommentTextType.Emoji && element.resource != null) {
      ImageSpan(element.resource)
        .width(EmoticonManager.emojiSideLengthForFontSize(this.contentFontSize))
        .height(EmoticonManager.emojiSideLengthForFontSize(this.contentFontSize))
        .verticalAlign(ImageSpanAlignment.CENTER)
        .onClick(() => {
         this.openCommentInput()
       })
    }
  })
}

這樣就完成了字符串到帶圖富文本的自動轉(zhuǎn)換

2.1 表情配置管理

想要實現(xiàn)表情圖片自動匹配,首先就需要先有表情圖片,要有對應(yīng)的表情配置表,項目中的表情配置分程序內(nèi)置默認(rèn)配置與線上后臺下發(fā)配置。

2.1.1 本地配置

我們采用字符串的形式,將配置表保存到管理類的靜態(tài)屬性中:

export class LocalEmoticon {
  static readonly data = '{"emoticons":[{"imageName":"icon_emotion_1","description":"[微笑]","id":44},{"imageName":"icon_emotion_2","description":"[嘻嘻]","id":43},{"imageName":"icon_emotion_3","description":"[笑哭]","id":42}, ... ]}'
}

這樣讀取字符串后直接映射就可以得到序列化好的類型數(shù)據(jù):

let jsonString = LocalEmoticon.data
const model = plainToClass(EmoticonConfigModel,JSON.parse(jsonString))

表情圖片文件直接放置在 resources -> base -> media 文件夾中,獲取的時候直接通過:

let str = 'app.media.' + imageName
let resourceStr = $r(str)

獲取 ResourceStr ,這里選取 media 文件夾是因為 運(yùn)行中生成的字符串不生效,但是r 可以

圖片圖片

2.1.2 線上配置

線上配置會下發(fā)配置表數(shù)據(jù)以及對應(yīng)的圖片壓縮包下載地址,配置表和本地配置一樣讀取并序列化就可以,但是圖片文件需要先下載到沙盒文件夾中再訪問。

鴻蒙中下載文件需要使用 request.downloadFile ,下載到指定的文件夾目錄后再使用 zlib.decompressFile 解壓縮到圖片存儲目錄。

讀取的時候拼接出文件地址,再通過 fileUri 獲取文件 uri 字符串就可以:

let path = EmoticonManager.getInstance().folderPath() + '/' + imageName
return fileUri.getUriFromPath(path)

這樣無論是本地配置還是線上配置獲取到的圖片資源都統(tǒng)一成了 ResourceStr 類型,直接丟給 ImageSpan 就可以加載出對應(yīng)圖片。

3.富文本輸入框

輸入框選用 RichEditor 組件。RichEditor 通過綁定 RichEditorController 來控制布局樣式和插入富文本內(nèi)容。

圖片圖片

圖片圖片

3.1 自定義表情面板

通過 customKeyboard 傳入自定義組件,并在點擊事件中通過 RichEditorController 來控制輸入框的插入和刪除:

RichEditor({controller:this.editorController})
  .key(this.editorKey)
  .customKeyboard(this.useCustomKeyboard ? this.emojiKeyboard():undefined)

//自定義鍵盤實體
@Builder emojiKeyboard() {
  EmojiKeyboard({
    currentWidth:this.currentWidth,
    emojiOnClick: (model) => { this.emojiOnClick(model) },
    deleteOnClick: () => { this.emojiOnDelete() }})
    .backgroundColor('#F2F5F7')
    .width('100%')
    .height(this.emojiKeyboardHeight)
    .onAreaChange((oldValue:Area,newValue:Area) => {
     if (typeof newValue.width === 'number') {
        this.currentWidth = newValue.width as number
      }
  })
}

//插入圖片
emojiOnClick(model: EmoticonModel) {
  this.editorController.addImageSpan(
    EmoticonManager.getInstance().getPixelMap(model.description),
    {imageStyle: {
      size:[EmoticonManager.emojiSideLengthForFontSize(this.fontSize),
            EmoticonManager.emojiSideLengthForFontSize(this.fontSize)],
      verticalAlign:ImageSpanAlignment.CENTER },
     offset: this.editorController.getCaretOffset() })
  }

//刪除按鈕點擊
emojiOnDelete() {
  const currentIndex = this.editorController.getCaretOffset() //獲取光標(biāo)位置
  if (currentIndex > 0) {
    this.editorController.deleteSpans({start:currentIndex-1,end:currentIndex})//從光標(biāo)位置向前刪除
  }
}

圖片圖片

3.2 獲取已輸入內(nèi)容

想要將輸入的富文本作為評論發(fā)送出去,還需要拿到轉(zhuǎn)譯之前的原始字符串,但是鴻蒙不是像 iOS 一樣給文字掛載樣式掛載圖片。iOS 這種給圖文掛載樣式的實現(xiàn)原始文字一直都在,直接獲取就可以了。鴻蒙的輸入框中的文字是文字組件,圖片是圖片組件,而且圖片組件里面只有圖片相關(guān)的屬性,沒有關(guān)聯(lián)文字的地方。只能先獲取所有組件,再反向轉(zhuǎn)譯。獲取全部組件是通過 RichEditorController 的 getSpans API 。

圖片圖片

但是從上面的截圖可以看到 getSpans 所獲取到的數(shù)組,內(nèi)容物是聯(lián)合類型,轉(zhuǎn)譯之前就需要先判斷。鴻蒙沒有像iOS isKindOfClass 一樣的判斷方法,由于 RichEditorImageSpanResult 比 RichEditorTextSpanResult 多了一個 imageStyle 屬性,鴻蒙官方推薦使用判斷該屬性是不是 undefined 的方式來區(qū)分類型:

if (typeof (element as RichEditorImageSpanResult)['imageStyle'] != 'undefined')

區(qū)分出類型之后,文字組件 RichEditorTextSpanResult 直接獲取 .value 就可以獲取到文字。圖片組件 RichEditorImageSpanResult 就麻煩一些,首先通過 .valueResourceStr 可以獲取到圖片的資源路徑 resource:///icon_emotion_8.png ,刨除協(xié)議頭 resource:/// 與文件后綴 .png ,就得到了圖片名 icon_emotion_8,通過配置表可以匹配到對應(yīng)的表情關(guān)鍵字"[鼓掌]"。這樣按照順序?qū)⑽淖纸M裝起來,就實現(xiàn)了富文本的反向轉(zhuǎn)譯。

責(zé)任編輯:武曉燕 來源: 搜狐技術(shù)產(chǎn)品
相關(guān)推薦

2023-04-07 07:14:34

2023-08-04 08:20:56

DockerfileDocker工具

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2023-09-10 21:42:31

2023-06-30 08:18:51

敏捷開發(fā)模式

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2023-11-03 12:54:00

KAFKA探索中間件

2022-02-23 08:41:58

NATIPv4IPv6

2022-09-22 08:06:29

計算機(jī)平板微信

2021-08-12 07:49:24

mysql

2024-11-28 09:57:50

C#事件發(fā)布器

2022-10-08 00:00:05

SQL機(jī)制結(jié)構(gòu)

2024-07-26 09:47:28

2023-03-26 23:47:32

Go內(nèi)存模型

2023-07-24 09:41:08

自動駕駛技術(shù)交通

2022-06-26 09:40:55

Django框架服務(wù)

2022-02-14 07:03:31

網(wǎng)站安全MFA

2022-10-28 07:27:17

Netty異步Future
點贊
收藏

51CTO技術(shù)棧公眾號