HarmonyOS鸿蒙Next中如何实现一个跑马灯效果?

HarmonyOS鸿蒙Next中如何实现一个跑马灯效果? 我们应该如何来实现一个跑马灯效果呢?

4 回复

使用Marquee组件实现文字跑马灯效果:

@Entry
@Component
struct MarqueeExample {
  @State start: boolean = false;
  @State fontSizeNum: number = 32;
  @State marqueeText: string =  '我是一串超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级超级长的文本';
  private fromStart: boolean = true;
  @State step: number = 10;
  build() {
    Column() {
      Marquee({
        start: this.start,
        step: this.step,
        loop: -1,
        fromStart: this.fromStart,
        src: this.marqueeText
      })
        .marqueeUpdateStrategy(MarqueeUpdateStrategy.PRESERVE_POSITION)
        .width('300vp')
        .fontColor('#FFFFFF')
        .fontSize(this.fontSizeNum)
        .fontWeight(700)
        .backgroundColor('#182431')
        .margin({ bottom: '40vp' })
        .onClick(()=>{
          this.fontSizeNum=this.fontSizeNum>16?16:this.fontSizeNum;
          this.start=!this.start;
        })
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
  }
}

效果图:

更多关于HarmonyOS鸿蒙Next中如何实现一个跑马灯效果?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


实现效果

https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtybbs/561/716/646/0030086000561716646.20251225225028.44738659796219157637146707013229:50001231000000:2800:7527C7C305D3DAF5F25BFB8F6B903BB0C7CFBB1B51800938EA10E445B8C5249C.gif

使用场景

股票行情滚动、播放器歌词显示、广告字幕条、电商促销信息跑马灯等

实现思路

本次实现比较简单,只需要通过一个组件即可解决:

第一步:使用Marquee来创建,Marquee是一个专门的跑马灯组件,用于滚动展示一段单行文本。

第二步:了解Marquee相关的属性,start: 开始 fromStart:滚动方向 src : 滚动的文本

Marquee({
        start: this.start,
        fromStart: this.fromStart,
        step: 2,
        src: this.message
      })

完整实现代码

@Entry
@Component
struct PaoMa {
  @State message: string = "盼望着,盼望着,东风来了,春天的脚步近了。一切都像刚睡醒的样子,欣欣然张开了眼。山朗润起来了,水涨起来了,太阳的脸红起来了。小草偷偷地从土里钻出来,嫩嫩的,绿绿的。园子里,田野里,瞧去,一大片一大片满是的。坐着,躺着,打两个滚,踢几脚球,赛几趟跑,捉几回迷藏。风轻悄悄的,草软绵绵的。 "
  @State start: boolean = true
  @State fromStart: boolean = true

  build() {
    Column() {
      Marquee({
        start: this.start,
        fromStart: this.fromStart,
        step: 2,
        src: this.message
      })

      Row() {
        Button("开始")
          .onClick(() => {
            this.start = true
          })
        Button("暂停")
          .onClick(() => {
            this.start = false
          })
        Button("切换方向")
          .onClick(() => {
            this.fromStart = !this.fromStart
          })
      }.margin({ top: 10 })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}

在HarmonyOS Next中实现跑马灯效果,可通过ArkUI的Marquee组件实现。该组件支持文本滚动,可设置滚动方向、速度及循环次数等属性。开发者需在UI中引入Marquee,配置相应参数即可完成基础跑马灯效果。无需额外编写复杂动画逻辑。

在HarmonyOS Next中,实现跑马灯效果(即文本水平滚动)的核心是使用Text组件结合动画。以下是两种主流且简洁的实现方案:

方案一:使用Scroll组件(简单快捷)

如果需求是简单的单行文本循环滚动,Scroll的滚动动画是最快的方式。

import { Scroll, Text } from '@kit.ArkUI';

@Entry
@Component
struct MarqueeDemo {
  private text: string = '这是一段需要滚动显示的跑马灯文本内容。';

  build() {
    Scroll() {
      Text(this.text)
        .fontSize(20)
        .textOverflow({ overflow: TextOverflow.None }) // 禁止换行
        .whiteSpace(WhiteSpace.Normal)
    }
    .scrollable(ScrollDirection.Horizontal) // 水平滚动
    .edgeEffect(EdgeEffect.None) // 去除边缘效果
    .onScrollEdge((side: ScrollEdge) => {
      // 滚动到边缘时触发,可用于实现循环逻辑
      if (side === ScrollEdge.End) {
        // 此处可添加跳转至开始的逻辑
      }
    })
  }
}

说明:此方案依赖用户手动滑动,若需自动滚动,需结合定时器或属性动画控制scrollBy方法。

方案二:使用属性动画(推荐,自动滚动)

通过属性动画改变文本的translateX位置,实现自动循环滚动。

import { Text, Stack } from '@kit.ArkUI';

@Entry
@Component
struct MarqueeDemo {
  @State private translateX: number = 0;
  private text: string = '这是一段需要滚动显示的跑马灯文本内容。';
  private containerWidth: number = 300; // 容器宽度,需根据实际获取
  private textWidth: number = 500; // 文本宽度,需根据实际获取

  aboutToAppear(): void {
    this.startAnimation();
  }

  startAnimation(): void {
    // 动画:从右侧初始位置滚动到完全消失
    animateTo({
      duration: 10000, // 滚动时长
      curve: Curve.Linear,
      iterations: -1, // 无限循环
      onFinish: () => {
        // 每次动画结束时重置位置,实现无缝衔接
        this.translateX = 0;
      }
    }, () => {
      this.translateX = -this.textWidth; // 滚动目标位置
    });
  }

  build() {
    // 使用Stack布局限制显示区域
    Stack({ alignContent: Alignment.Start }) {
      Text(this.text)
        .fontSize(20)
        .textOverflow({ overflow: TextOverflow.None })
        .whiteSpace(WhiteSpace.Normal)
        .translate({ x: this.translateX }) // 应用水平位移动画
        .onAreaChange((oldArea, newArea) => {
          // 获取文本实际渲染宽度
          this.textWidth = newArea.width;
        })
    }
    .width(this.containerWidth)
    .clip(true) // 关键:裁剪超出容器部分
    .onAreaChange((oldArea, newArea) => {
      // 获取容器宽度
      this.containerWidth = newArea.width;
    })
  }
}

关键点说明

  1. 布局与裁剪:使用StackFlex限定显示区域,并设置.clip(true)确保文本超出部分被裁剪。
  2. 文本测量:通过onAreaChange回调获取文本和容器的实际宽度,用于计算滚动距离。
  3. 动画控制
    • iterations: -1实现无限循环。
    • onFinish回调中重置位置,实现无缝滚动。
  4. 性能优化:对于复杂场景,可使用Canvas绘制文本,但上述方案已满足多数UI需求。

扩展建议

  • 若需要暂停/恢复滚动,可使用animateTodelay参数或控制动画状态。
  • 多行或复杂内容滚动,建议使用List实现。

以上方案二为完整自动滚动实现,直接复制并调整参数即可使用。

回到顶部