HarmonyOS Next 计时器组件详解

背景介绍

在日常UI开发中,经常会用到计时控件,比如播放视频是的时间进度显示以及音视频通话时显示的通话时长,都需要用到正计时的计时控件。还有些场景会用到倒计时的计时控件,设置一个最大时间,开始倒计时。在Android中我们一般使用TextView,配合Handler来更新TextView实现计时效果。HarmonyOS Next提供了TextTimer组件来实现计时效果。下面先介绍TextTimer能力。

TextTimer 介绍

TextTimer 是一个通过文本显示计时信息并控制其计时器状态的组件。在组件不可见时时间变动将停止,组件的可见状态基于onVisibleAreaChange处理,可见阈值ratios大于0即视为可见状态。

属性介绍
  • format(value: string):设置自定义格式,需至少包含一个HH、mm、ss、SS中的关键字。如使用yy、MM、dd等日期格式,则使用默认值。
  • fontColor(value: ResourceColor):设置字体颜色。
  • fontWeight (value: number | FontWeight | string):设置文本的字体粗细,设置过大可能会在不同字体下有截断。number 类型取值 [100, 900],取值间隔为 100,默认为 400,取值越大,字体越粗。string 类型仅支持 number 类型取值的字符串形式(例如 "400"),以及 "bold"、"bolder"、"lighter"、"regular"、"medium",分别对应 FontWeight 中相应的枚举值。
  • fontFamily (value: ResourceStr):设置字体列表,默认字体为 'HarmonyOS Sans'。应用当前支持 'HarmonyOS Sans' 字体和注册自定义字体,卡片当前仅支持 'HarmonyOS Sans' 字体。
  • textShadow(value: ShadowOptions | Array<ShadowOptions>):设置文字阴影效果,该接口支持以数组形式入参实现多重文字阴影,不支持 fill 字段,不支持智能取色模式。
  • contentModifier(modifier: ContentModifier<TextTimerConfiguration>):定制 TextTimer 内容区的方法,modifier 为内容修改器,开发者需要自定义 class 实现 ContentModifier 接口。

TextTimer构造中需要传入TextTimerOptions对象,TextTimerOptions包含下面属性:

名称 类型 必填 说明
isCountDown boolean 是否倒计时。值为true时,计时器开启倒计时,值为false时,计时器开始计时。 默认值:false
count number 计时器时间(isCountDown为true时生效),单位为毫秒。最长不超过86400000毫秒(24小时)。 0<count<86400000时,count值为计时器初始值。否则,使用默认值为计时器初始值。 默认值:60000
controller TextTimerController TextTimer控制器。

其中TextTimerController 主要用于控制计时器的开启、暂停等:

  • start():计时开始。
  • pause():计时暂停。
  • reset():重置计时器。
事件介绍

主要包含onTimer事件:

  • onTimer (event: (utc: number, elapsedTime: number) => void):时间文本发生变化时触发,锁屏状态和应用后台状态下不会触发该事件。设置高精度的 format(SSS、SS)时,回调间隔可能会出现波动。参数 utc 为 Linux 时间戳,即自 1970 年 1 月 1 日起经过的时间,单位为设置格式的最小单位;elapsedTime 为计时器经过的时间,单位为设置格式的最小单位。

使用示例

示例一:按钮控制计时器
复制代码
@Entry
@Component
struct TextTimerExample {
  textTimerController: TextTimerController = new TextTimerController()
  @State format: string = 'mm:ss.SS'

  build() {
    Column() {
      TextTimer({ isCountDown: true, count: 30000, controller: this.textTimerController })
        .format(this.format)
        .fontColor(Color.Black)
        .fontSize(50)
        .onTimer((utc: number, elapsedTime: number) => {
          console.info('textTimer notCountDown utc is:' + utc + ', elapsedTime: ' + elapsedTime)
        })
      Row() {
        Button("start").onClick(() => {
          this.textTimerController.start()
        })
        Button("pause").onClick(() => {
          this.textTimerController.pause()
        })
        Button("reset").onClick(() => {
          this.textTimerController.reset()
        })
      }
    }
  }
}

效果:

示例二:自动执行计时
复制代码
@Entry
@Component
struct TextTimerStart {
  textTimerController: TextTimerController = new TextTimerController()
  @State format: string = 'mm:ss.SS'

  build() {
    Column() {
      Scroll()
        .height('20%')
      TextTimer({ isCountDown: true, count: 30000, controller: this.textTimerController })
        .format(this.format)
        .fontColor(Color.Black)
        .fontSize(50)
        .onTimer((utc: number, elapsedTime: number) => {
          console.info('textTimer notCountDown utc is:' + utc + ', elapsedTime: ' + elapsedTime)
        })
        .onAppear(() => {
          this.textTimerController.start()
        })
    }
  }
}

使用局限性

针对正计时场景,每次都是从0开始,有些场景我们期望从某个时间开始计时。比如针对页面切换场景,在视频通话场景,在全屏画面时和悬浮窗时是两个页面,从全屏切换到悬浮窗时希望计时是连续的而不是从0开始,怎么办?

TextTimer提供了内容区域定制的方法:contentModifier,这里需要我们实现一个 ContentModifier<TextTimerConfiguration>

  1. 首先需要实现一个MyTextTimerModifier, applyContent方法中封装Builder方法;
  2. 在自定义Builder方法中自定义UI;
  3. 调用contentModifier将自定义的MyTextTimerModifier实现配置到TextTimer;
  4. 需要删除TextTimer的 颜色和字体配置,通过自定义UI中配置
  5. format设置会影响elapsedTime的单位
  6. config.elapsedTime加一个初始值就实现了从某个时间开始计时
  7. 将秒转换为mm:ss格式

下面是代码示例:

复制代码
let startTime:number = 100;  
  
function formatData(diffTimeBySecond: number): string {  
  const hours = Math.floor(diffTimeBySecond / 3600);  
  const minutes = Math.floor((diffTimeBySecond % 3600) / 60);  
  const remainingSeconds = Math.floor(diffTimeBySecond % 60);  
  
  // 补零函数  
  const pad = (num: number) => num.toString().padStart(2, '0');  
  
  return hours > 0  
    ? `${pad(hours)}:${pad(minutes)}:${pad(remainingSeconds)}`  
    : `${pad(minutes)}:${pad(remainingSeconds)}`;  
}  
class MyTextTimerModifier implements ContentModifier<TextTimerConfiguration> {  
  constructor() {  
  }  
  applyContent(): WrappedBuilder<[TextTimerConfiguration]> {  
    return wrapBuilder(buildTextTimer)  
  }  
}  
  
@Builder  
function buildTextTimer(config: TextTimerConfiguration) {  
  Column() {  
      Column() {  
        Text(formatData(config.elapsedTime + startTime)).fontColor(Color.Red)  
    }  
  }}  
  
@Entry  
@Component  
struct Index {  
  @State count: number = 10000  
  @State myTimerModifier: MyTextTimerModifier = new MyTextTimerModifier()  
  countUpTextTimerController: TextTimerController = new TextTimerController()  
  
  build() {  
    Row() {  
      Column() {  
        TextTimer({ isCountDown: false, controller: this.countUpTextTimerController })  
          .contentModifier(this.myTimerModifier)  
          .onTimer((utc: number, elapsedTime: number) => {  
            console.info('textTimer onTimer utc is:' + utc + ', elapsedTime: ' + elapsedTime)  
          })  
        Row() {  
          Button("start").onClick(() => {  
            this.countUpTextTimerController.start()  
          }).margin(10)  
          Button("pause").onClick(() => {  
            this.countUpTextTimerController.pause()  
          }).margin(10)  
          Button("reset").onClick(() => {  
            this.countUpTextTimerController.reset()  
          }).margin(10)  
        }.margin(20)  
      }.width('100%')  
    }.height('100%')  
  }  
}

最终效果如下:

相关推荐
fatiaozhang95272 小时前
晶晨S905L3A(B)-安卓9.0-开启ADB和ROOT-支持IPTV6-支持外置游戏系统-支持多种无线芯片-支持救砖-完美通刷线刷固件包
android·游戏·adb·华为·电视盒子·机顶盒rom·魔百盒固件
用户545748341772 小时前
Harmonyos5应用开发实战——地图组件集成与定位功能实现(part1)
harmonyos
用户545748341772 小时前
Harmonyos5应用开发实战——订单页面开发(part2)
harmonyos
用户545748341772 小时前
Harmonyos5应用开发实战——地图组件集成与定位功能实现(part2)
harmonyos
用户545748341772 小时前
HarmonyOS Next应用开发实战——登录页面实现(part1)
harmonyos
用户545748341772 小时前
HarmonyOS Next应用开发实战——底部弹框组件的实现(part1)
harmonyos
用户545748341772 小时前
HarmonyOS Next应用开发实战——底部弹框组件的实现(part2)
harmonyos
用户545748341773 小时前
HarmonyOS Next应用开发实战——多功能页面组件构建(part1)
harmonyos
用户545748341773 小时前
HarmonyOS Next应用开发实战——多功能页面组件构建(part2)
harmonyos
星释3 小时前
鸿蒙Flutter实战:18-组合而非替换,现有插件快速鸿蒙化
flutter·华为·harmonyos