来自云龙湖轮廓分明的月亮 发表于 2025-3-14 13:06:12

【HarmonyOS NEXT】实现文字环绕动态文本效果

一、配景

在开发鸿蒙应用时,我们常常需要实现一些复杂的布局效果,好比文字环绕动态文本的效果。这种效果类似于文字环绕图片,但需要环绕的文本是动态生成的,并且带有边框和样式。传统的布局组件(如 Row)无法直接实现这种效果,由于 Row 的换行逻辑是基于每个子组件的起始端,无法实现第二个文本环绕第一个文本的效果。
下面介绍如何通过 组件截图 和 ImageSpan 来实现文字环绕动态文本的效果。
二、实现思路

1. 初步实验:使用 Row 组件

最初的想法是使用 Row 组件包裹两个 Text 组件,分别表示需要环绕的文本和主文本。然而,Row 组件的布局方式是左右排列,当文本换行时,第二个 Text 组件会基于自己的起始端换行,无法实现环绕效果。
如下效果:
https://i-blog.csdnimg.cn/direct/49d20c8e27c24c7998685ea52bee196c.png
2. 解决方案:组件截图 + ImageSpan

为了实现文字环绕效果,采用了以下方案:

[*] 使用 componentSnapshot 组件对需要环绕的文本进行截图,生成图片。
[*] 将截图通过 ImageSpan 嵌入到主文本中,实现文字环绕图片的效果。
三、详细实现

3.1 组件截图:componentSnapshot

componentSnapshot 是鸿蒙 ArkUI 提供的一个 API,用于获取组件的截图。它支持截取已加载组件的内容,并将结果保存为 PixelMap 对象。
3.1.1 导入模块

起首,需要导入 componentSnapshot 模块:
import { componentSnapshot } from '@kit.ArkUI'; 3.1.2 界说需要截图的组件

我们界说一个带有边框和样式的 Text 组件,作为需要环绕的文本:
//获取需要加载组件的文本
@Builder
hotTopText() {
    Text('精选')
      .borderRadius(2)
      .border({
      width: 0.5,
      color: '#0165B8',
      style: BorderStyle.Solid
      })
      .fontSize(12)
      .fontColor('#0165B8')
      .backgroundColor('#DBEFFF')
      .padding({
      left: 2,
      right: 2
      })
      .margin({ top: 5 })
      .height(15)
      .id('hotTopText') //组件标识
      .visibility(this.isShowTag ? Visibility.Visible : Visibility.None)
} 3.1.3 获取组件截图

通过 componentSnapshot.get 方法获取组件的截图:
getComponentSnapshot() {
    this.isShowTag = true
    // 增加延迟,确保组件渲染完成
    setTimeout(() => {
      componentSnapshot.get('hotTopText', { scale: 2, waitUntilRenderFinished: true })
      .then((pixmap: image.PixelMap) => {
          this.pixmap = pixmap;
          this.isShowTag = false
      })
      .catch(() => {
          console.log('lucy== 获取标签快照失败')
      });
    }, 100);
} 3.2 使用 ImageSpan 实现文字环绕

将截图通过 ImageSpan 嵌入到主文本中,实现文字环绕效果:
    Row() {
      this.hotTopText() //只有加载了才能获取截图
      Text() {
      ImageSpan(this.pixmap)
          .height(14)
          .width('auto')
          .verticalAlign(ImageSpanAlignment.CENTER)
          .margin({ right: 3 })
          .objectFit(ImageFit.Contain)
      Span('HarmonyOS NEXT 全栈自研架构,鸿蒙原生应用,带来全新体验')
          .fontSize(15)
          .fontWeight(FontWeight.Medium)
      }
      .align(Alignment.Top)
      .textAlign(TextAlign.Start)

    }
    .margin({
      top: 12,
    })
    .padding(12)
    .borderWidth(1)
    .borderColor(Color.Red) 四、完整代码

以下是完整的实现代码:
import { image } from '@kit.ImageKit'import { componentSnapshot } from '@kit.ArkUI'@Entry@Componentstruct TextSpanPage {@State pixmap: image.PixelMap | undefined = undefined@State isShowTag: boolean = falseaboutToAppear(): void {    this.getComponentSnapshot()}getComponentSnapshot() {
    this.isShowTag = true
    // 增加延迟,确保组件渲染完成
    setTimeout(() => {
      componentSnapshot.get('hotTopText', { scale: 2, waitUntilRenderFinished: true })
      .then((pixmap: image.PixelMap) => {
          this.pixmap = pixmap;
          this.isShowTag = false
      })
      .catch(() => {
          console.log('lucy== 获取标签快照失败')
      });
    }, 100);
}build() {    Row() {
      this.hotTopText() //只有加载了才能获取截图
      Text() {
      ImageSpan(this.pixmap)
          .height(14)
          .width('auto')
          .verticalAlign(ImageSpanAlignment.CENTER)
          .margin({ right: 3 })
          .objectFit(ImageFit.Contain)
      Span('HarmonyOS NEXT 全栈自研架构,鸿蒙原生应用,带来全新体验')
          .fontSize(15)
          .fontWeight(FontWeight.Medium)
      }
      .align(Alignment.Top)
      .textAlign(TextAlign.Start)

    }
    .margin({
      top: 12,
    })
    .padding(12)
    .borderWidth(1)
    .borderColor(Color.Red)}//获取需要加载组件的文本
@Builder
hotTopText() {
    Text('精选')
      .borderRadius(2)
      .border({
      width: 0.5,
      color: '#0165B8',
      style: BorderStyle.Solid
      })
      .fontSize(12)
      .fontColor('#0165B8')
      .backgroundColor('#DBEFFF')
      .padding({
      left: 2,
      right: 2
      })
      .margin({ top: 5 })
      .height(15)
      .id('hotTopText') //组件标识
      .visibility(this.isShowTag ? Visibility.Visible : Visibility.None)
}} 五、最终效果
通过以上方法,实现了文字环绕动态文本的效果。动态文本被截图为图片,并通过 ImageSpan 嵌入到主文本中,实现了类似文字环绕图片的布局效果。
https://i-blog.csdnimg.cn/direct/50f578a224284970a0db6050def451bf.png
https://i-blog.csdnimg.cn/direct/d127ea96239647669b32d3d7534e275f.png


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【HarmonyOS NEXT】实现文字环绕动态文本效果