鸿蒙中富文本编辑与展示

                富文本在鸿蒙系统如何展示和编辑的?在文章开头我们提出这个疑问,带着疑问来阅读这篇文章。

                富文本用途可以展示图文混排的内容,在日常App 中非常常见,比如微博的发布与展示,朋友圈的发布与展示,都在使用富文本的编辑与展示。通常我们需要标注不同颜色文本,比如话题,#富文本编辑与展示#,@鸿蒙开发者等,这些都要在编辑时或者发布后展示时标注不同的字体颜色。

一、功能富文本编辑

            

我们如何实现上边这个富文本编辑器呢,在鸿蒙中通过RichEditor实现,由于官网对RichEditor示例太多,很多开发者找不到自己想要的结果,或者对应的使用实例,下面几个部分,基本满足大部分开发者需求的编写。首先上边有四个主要部分,

1、@某人 的实现;主要包括@某人的添加和删除,通过添加@某人,可以看到添加的时候对颜色进行标红,并设置字体大小。

addAltInfo = (referInfo: ReferInfo) => {
  this.referInfos.push(referInfo)
  let tempText = `@${referInfo.mUserName} `
  this.richEditorController.addTextSpan(
    tempText,
    {
      style: {
        fontColor: $r("app.color.v5_theme_color"),
        fontSize: 15
      }
    }
  )
}

添加完删除时候我们需要判断是否以@开头,如果已@开头就把Span相关的全部删掉。否则就按照系统本身删除 即可。

if (needValue.startsWith("@")) {
  // @时候删除全部
  for (let index = 0; index < this.referInfos.length; index++) {
    let referInfo = this.referInfos[index] as ReferInfo
    let altNickname = `@${referInfo.mUserName} `
    if (altNickname == needValue) {
      this.referInfos.splice(index, 1)
      this.richEditorController.deleteSpans({ start, end })
      deleteFlag = false
    }
  }
}

2、#话题内容# 的实现与@某人相似,通过#选的话题#,这样来设置添加文本的颜色,字体大小等

addTopic = (topic: string) => {
  this.richEditorController.addTextSpan(
    topic,
    {
      style: {
        fontColor: $r("app.color.v5_theme_color"),
        fontSize: 15
      }
    }
  )
}

如果在删除时候,我们判断一下span内人字符串是已#开始,我们认为他是输入的话题,这时候我们需要把他的字体颜色改变为普通文本的颜色,这样就可以变成普通文本了。目前我是以#开始计算的,你也可以加上以#开始,并且#结束的时候才改变其颜色。我认为以#开始已经足够了。

 if (needValue.startsWith("#")) {
  this.richEditorController.updateSpanStyle(
    {
      start: start,
      end: end,
      textStyle: {
        fontColor: $r("app.color.title"),
        fontSize: 15
      }
    }
  )
}

3、自定义表情实现,就是我们App 内自己定义一些相关的表情符号,选择对应的表情,以图片的形式存放在发布微博中。这里FaceID就是我们图片资源。可以设置图片的大小,根据自己需求设置大小。表情的删除因为是ImageSpan所以表情就一块删掉了,不用担心删除一半问题。直接按照系统方法走删除的逻辑就可以了。

addFace = (faceId: Resource) => {
  this.richEditorController.addImageSpan(
    faceId,
    {
      imageStyle: {
        size: [16, 16]
      }
    }
  )
  this.addDefaultStyle()
}

4、基本文本文字输入我们有二种方案,第一种就是每次输入完之后加一个空格,来改变后边字体的颜色的字体大小,这样就不会每次跟着前边的字体大小和颜色了。还有一种就是在每次输入完更新输入的字体颜色,把自己输入改为默认颜色即可。二种目前都不是最优解,但是可以解决临时现在的问题,如果大家有好的办法我们一起交流。目前华为官网也没有很好的例子来实现。

addDefaultStyle(text?: string) {
  let tempText = " "
  if (text) {
    tempText = text
  }
  this.richEditorController.addTextSpan(
    tempText,
    {
      style: {
        fontColor: $r("app.color.title"),
        fontSize: 15
      }
    }
  )
}

这种是在每次文本输入的时候改变文本的颜色。

.onDidIMEInput((textRange: TextRange) => {
  this.richEditorController.updateSpanStyle({
    start: textRange.start,
    end: textRange.end,
    textStyle: {
      fontColor: $r("app.color.title"),
      fontSize: 15
    }
  })
})

5、实时获取文本输入的长度字数,以控制最大输入长度。实现方法就是通过getSpans()或者所有的文本,如果是ImageSpan替换成对应的字符串计算字符。其他的按照文本方式计算。直接累加字符串得到最后的文本。得到文本直接获取他的长度即可。

getInputResult = (): string => {
  let resultStr: string = ""
  let resultList = this.richEditorController.getSpans()
  for (let result of resultList) {
    if (typeof (result as RichEditorImageSpanResult)['imageStyle'] != 'undefined') {
      let valueResourceStr = (result as RichEditorImageSpanResult).valueResourceStr
      if (valueResourceStr) {
        let index = FaceList.getRealIds().indexOf(valueResourceStr.toString())
        let faceStr = FaceList.faceNameStr[index]
        resultStr += faceStr
      }
    } else {
      let value = (result as RichEditorTextSpanResult).value
      resultStr += value
    }
  }
  return resultStr
}

6、对于输入框编辑器对文本的限制,我们可以通过将要输入内容是否还接收数据来实现,如果已经达到我们要求的最大长度我们可以将onWillChange设置成false来表示不在接收数据即可。

.onWillChange((_changeValue) => {
  if (this.getInputResult().length >= this.maxLength) {
    return false
  }
  return true
})

通过监听onDidChange输入之后数据改变实现输入后数据的变化和输入长度展示。

.onDidChange((_callback) => {
  this.inputDataChange(this.getInputResult())
})

通过上边几个部分的讲解,我们基本完成的富文本编辑在鸿蒙上边的实现,可以通过上边步骤实现类似微博的发布功能,主要包括文本输入,#话题选择#,@某人,文本删除的功能,基本满足的富文本编辑的需求,如果有不满足的你的需求,可以私信我,我们一起探讨,欢迎你的提起,我们一起进步,共同成长。

二、富文本的展示

富文本的展示指的什么,我们需要展示哪些内容;首先举个例子,文本中链接、#话题#、@鸿蒙开发者、表情图标等这些内容需要再展示时候标注特殊的颜色,点击时候我们需要跳转到对应的界面,在鸿蒙中我们怎么在一串文字文本中,对不同文字设置不同的颜色,并且在点击时候跳转对应的界面呢,展示文字中的图片呢,带着这些问题我们来看下边的内容。

首先鸿蒙提供了文本展示器Text,我们可以通过Text展示,但是如果想特殊标记颜色,我们就需要对文本进行分割了,分割出每段要展示的内容。这里我们以#话题#,链接为例进行分割。这里以通过正则表达式分割之后,以#结束的,我们认为是话题类型,否则认为是长链接。这里的分割内容是把#话题#,长链接分割分割出来。分割出来之后,我们通过字符串把整个文本进行分割成不同内容。最后分割成三种类型,普通文本、话题、长链接类型,然后根据类型,展示对应的问题,如果需要跳转点击文本时候进行跳转。@某人、表情符号分割和这个类似方式,这里不再重复表述。如有疑问请私信提出。

export function splitContent(str: string): LinkTextModel[] {
  let data =
    str.match(/(#([^#]+)#)|(https?|rtsp):\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z0-9]{2,}(:[0-9]{1,5})?(\/[\S]*)?|(?<!\S)[a-zA-Z0-9\-]+(\.[a-zA-Z0-9]{2,})+(?!\S|\@)/gi);
  let result: LinkTextModel[] = [];
  let start = 0;
  let tempStr = str
  data?.forEach((value) => {
    let tempIndex = tempStr.indexOf(value)
    result.push({ type: LinkTextEnum.COMMON, content: tempStr.slice(start, tempIndex) })
    if (value.startsWith("#")) {
      result.push({ type: LinkTextEnum.TOPIC, content: value })
    } else {
      result.push({ type: LinkTextEnum.URl, content: value })
    }
    tempStr = tempStr.substring(tempIndex + value.length)
  });
  result.push({ type: LinkTextEnum.COMMON, content: tempStr })
  return result;
}

分割好的文本是一段一段的,我们需要把这些一段一段的展示出来。如下图所示,根据分割的类型展示不同颜色的问题。这里我们在Text里面用,Span展示文本,设置字体颜色。通过ImageSpan展示图标来展示表情。

  Text() {
    ForEach(this.allTextList, (item: LinkTextModel) => {
      if (item.type === LinkTextEnum.TOPIC) {
        ForEach(splitFace(item.content), (item: LinkChildModel) => {
          if (item.type === LinkTextEnum.Face && item.faceId) {
            ImageSpan(item.faceId)
              .width(16)
              .height(16)
          } else {
            Span(item.content)
              .fontColor("#A34444")
              .onClick(() => {
                // 跳转话题详情
              })
          }
        })
​
      } else if (item.type === LinkTextEnum.URl) {
        Span(item.content)
          .fontColor("#A34444")
          .onClick(() => {
             // 跳转Web加载页面,加载web地址
          })
      } else if (item.type == LinkTextEnum.ALT) {
        Span(item.content)
          .fontColor("#A34444")
          .onClick(() => {
             // alt 分割跳转个人详情
          })
      } else {
        ForEach(splitFace(item.content), (item: LinkChildModel) => {
          if (item.type === LinkTextEnum.Face && item.faceId) {
            ImageSpan(item.faceId)
              .width(16)
              .height(16)
          } else {
            Span(item.content)
          }
        })
      }
    })
  }
  .fontSize(14)
  .fontColor("#333333")
  .width(CommonConstants.MATCH_PARENT)
  .margin({ top: 5 })
  .padding({ left: 12, right: 12 })
}

阅读本文章,我们已经了解了富文本编辑器的实现,可以按照步骤一步一步实现自己的富文本编辑器,也学会富文本的展示,通过正则表达式分割自己需要的内容,然后通过Text中的span、imagespan组件展示分割的内容,本章节就介绍这些东西。后续章节我将依次从简入深,讲解鸿蒙的开发中遇到各种问题。欢迎大家一起交流。如果你在鸿蒙开发中遇到难点,不会的可以私信我,根据我最近的开发经历,已经基本踩完大部分坑,一起交流使我们共同进步。

    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/901367.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch 中的高效按位匹配

作者&#xff1a;来自 Elastic Alexander Marquardt 探索在 Elasticsearch 中编码和匹配二进制数据的六种方法&#xff0c;包括术语编码&#xff08;我喜欢的方法&#xff09;、布尔编码、稀疏位位置编码、具有精确匹配的整数编码、具有脚本按位匹配的整数编码以及使用 ESQL 进…

Maven 不同环境灵活构建

需求: 使用 Maven根据不同的构建环境&#xff08;如开发、测试、生产&#xff09;来定义不同的配置&#xff0c;实现灵活的构建管理。 需要Demo项目的可以参考&#xff1a;我的demo项目 一、项目分层 一般的初创项目不会有特别多的配置文件&#xff0c;所以使用 spring.profile…

【333基于Java Web的考编论坛网站的设计与实现

毕 业 设 计&#xff08;论 文&#xff09; 考编论坛网站设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计…

linux下gpio模拟spi三线时序

目录 前言一、配置内容二、驱动代码实现三、总结 前言 本笔记总结linux下使用gpio模拟spi时序的方法&#xff0c;基于arm64架构的一个SOC&#xff0c;linux内核版本为linux5.10.xxx&#xff0c;以驱动三线spi(时钟线sclk&#xff0c;片选cs&#xff0c;sdata数据读和写使用同一…

「二叉树进阶题解:构建、遍历与结构转化全解析」

文章目录 根据二叉树创建字符串思路代码 二叉树的层序遍历思路代码 二叉树的最近公共祖先思路代码 二叉搜索树与双向链表思路代码 从前序与中序遍历序列构造二叉树思路代码 总结 根据二叉树创建字符串 题目&#xff1a; 样例&#xff1a; 可以看见&#xff0c;唯一特殊的就…

SCI被「On Hold」意味着什么?会有哪些影响?

本文首发于“生态学者”微信公众号&#xff01; 继Chemosphere在2023年7月被「On Hold」之后&#xff0c;昨晚Science of The Total Environment 被标记为「On Hold」状态在各大公众号和朋友圈被刷屏&#xff01;&#xff08;官方网址&#xff1a;https://mjl.clarivate.com/s…

PouchDB - 免费开源的 JavaScript 数据库,轻量易用,用于离线保存数据的场景

这个 JS 工具库可以让我们很容易地实现数据缓存到本地的需求&#xff0c;要写的代码量也很少。 PouchDB 是一个基于 JavaScript 语言开发的轻量级的数据库&#xff0c;可以在浏览器、Node.js 等环境中使用。作者是一位来自国外的女开发工程师 Alba Herreras。 这是一个运行在浏…

el-datepicker禁用未来日期(包含时分秒)type=‘datetime’

文章目录 实现代码方式1&#xff1a;当选中日期的时候去更新一次。方式2: 优化版本&#xff0c;使用 setTimout 每分钟更新一次。&#xff08;防止选中日期之后过了很久再去选择时分秒时没有根据当前时间去改变&#xff09; el-datepicker 选择器禁用未来日期&#xff0c;动态禁…

重生之“我打数据结构,真的假的?”--2.单链表(无习题)

C语言中的单链表总结 单链表是一种基础的数据结构&#xff0c;广泛应用于C语言编程中。它由节点组成&#xff0c;每个节点包含数据和指向下一个节点的指针。单链表的优点在于动态内存分配和高效的插入与删除操作。本文将详细探讨单链表的定义、基本操作、应用场景以及相关示例…

Gateway 统一网关

一、初识 Gateway 1. 为什么需要网关 我们所有的服务可以让任何请求访问&#xff0c;但有些业务不是对外公开的&#xff0c;这就需要用网关来统一替我们筛选请求&#xff0c;它就像是房间的一道门&#xff0c;想进入房间就必须经过门。而请求想要访问微服务&#xff0c;就必须…

ComfyUI系列——新手安装ComfyUI,就是这么简单

比较Midjoury、WebUI和ComfyUI 在了解ComfyUI的时候&#xff0c;还有其它两款类似的产品&#xff0c;于是就搜集了一下资料&#xff0c;以下是Midjoury、WebUI&#xff08;通常指的是Stable Diffusion Web UI&#xff09;和ComfyUI三者之间的异同点对比表。 特性MidjourneySt…

国内短剧系统源码搭建系统平台小程序新玩法

在数字化内容消费日益普及的今天&#xff0c;短剧小程序作为一种新兴的内容平台&#xff0c;其功能设计至关重要。一个好的短句系统不仅需要提供优质的内容展示&#xff0c;还需要具备一系列优秀功能以满足用户和运营者的需求。以下是一些必备的功能特点&#xff1a; 为大家介…

WebGL 添加背景图

1. 纹理坐标&#xff08;st坐标&#xff09;简介 ST纹理坐标&#xff08;也称为UV坐标&#xff09;是一种二维坐标系统&#xff0c;用于在三维模型的表面上精确地定位二维纹理图像。这种坐标系统通常将纹理的左下角映射到(0,0)&#xff0c;而右上角映射到(1,1)。 S坐标&#x…

leetcode_128:最长连续序列

给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1&#xff1a; 输入&#xff1a;nums [100,4,200,1,3,2] 输出&#xff1a;4 解…

CSS揭秘:7. 伪随机背景

前置知识&#xff1a;CSS 渐变&#xff0c;5. 条纹背景&#xff0c;6. 复杂的背景图案 前言 本篇主要内容依然是关于背景的&#xff0c;无限平铺的背景会显得整齐美观&#xff0c;但又有些呆板&#xff0c;如何实现背景的多样性和随机性&#xff0c;是本篇的核心。 一、四种颜…

AI周报(10.20-10.26)

AI应用-牙科AI产品Pearl Pearl是一家致力于改善牙科患者护理的人工智能驱动型公司&#xff0c;推出了首款获得美国食品药品监督管理局&#xff08;FDA&#xff09;批准的人工智能&#xff0c;能够读取牙科X光片并即时识别疾病。今年7月获得5800万美元的B轮融资&#xff0c;以加…

GESP一级真题分析-202303-选择题1-输入输出设备、存储单位、默认数据类型、标识符命名

PDF文档回复:20241026 1 相关知识点 1) 输入输出设备 输入设备 是外界向计算机传送信息的装置。在微型计算机系统中&#xff0c;最常用的输入设备是键盘和鼠标。 此外还有电子光笔、数字化仪、图形扫描仪、触摸屏、麦克风、视频输入设备、条形码扫描等 输出设备 作用是将计…

Java-图书管理系统

我的个人主页 欢迎来到我的Java图书管理系统&#xff0c;接下来让我们一同探索如何书写图书管理系统吧&#xff01; 1管理端和用户端 2建立相关的三个包&#xff08;book、operation、user&#xff09; 3建立程序入口Main类 4程序运行 1.首先图书馆管理系统分为管理员端和…

6.stm32 OLED显示屏

调试方式 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息 显示屏调试&#xff1a;直接将显示屏连接到单片机&#xff0c;将调试信息打印在显示屏上 Keil调试模式&#xff1a;借助Keil软件的调试模式&#…

【阅读笔记】Instruction-based Hypergraph Pretraining

Abstract中可以提炼的信息&#xff1a; 背景&#xff1a;预训练的作用是为了增强图学习模型将知识从大数据集转移到下游任务的适应性。 想解决的问题&#xff1a;训练目标的不同与数据分布的不同会阻碍预训练知识的迁移。 文章受到基于指令的提示词在语言模型训练广泛应用的启发…