HarmonyOS Next音乐播放器进度条开发

整岛铁盒
发布于 2025-3-14 16:57
1899浏览
0收藏

一、概述

在移动应用开发中,音乐播放器的进度控制是核心交互功能之一。本文将以HarmonyOS ArkUI的Slider组件为基础,详细讲解如何实现一个功能完备的音乐播放器进度条组件,涵盖时间同步、播放控制、手势交互等关键技术点。

二、实现效果

  • 实时显示播放进度(MM:SS格式)
  • 支持拖动滑块进行进度跳转
  • 自动时间更新与手动控制同步
  • 播放/暂停/停止功能集成
  • 自定义进度条样式
  • 效果图

HarmonyOS Next音乐播放器进度条开发-鸿蒙开发者社区

三、代码实现

3.1 状态管理

@State currentTime: number = 0;   // 当前播放时间(秒)
@State totalTime: number = 238;   // 总时长(秒)
@State isPlaying: boolean = false; // 播放状态
private timerId: number = 0;       // 计时器ID
  • 1.
  • 2.
  • 3.
  • 4.


使用ArkUI的@State装饰器实现响应式数据绑定,当这些状态变化时自动触发UI更新。

3.2 Slider组件配置

Slider({
        value: this.currentTime,
        min: 0,
        max: this.totalTime,
        step: 1,
        style: SliderStyle.OutSet // 进度条样式
      })
        .blockColor(Color.Blue) // 滑块颜色
        .trackColor(Color.Gray) // 背景轨道颜色
        .selectedColor(Color.Blue) // 进度颜色
        .showSteps(false) // 隐藏步进点
        .onChange((value: number) => { // 拖动事件
          this.onSliderChange(value);
        })
        .width('90%')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.


关键参数说明:

  • value:双向绑定当前播放时间
  • min/max:设置时间范围
  • step:1:按秒级精度控制
  • style:使用突出样式增强可视性

3.3 时间同步机制

// 定时器更新逻辑
this.timerId = setInterval(() => {
  if (this.currentTime < this.totalTime) {
    this.currentTime += 1;
  } else {
    clearInterval(this.timerId);
    this.isPlaying = false;
  }
}, 1000);

// 格式化显示
private formatTime(seconds: number): string {
  const mins = Math.floor(seconds / 60);
  const secs = seconds % 60;
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.


实现秒到分钟转换,使用padStart保证两位数显示格式。

3.4 交互事件处理

// 播放/暂停控制
  private togglePlay() {
    if (this.isPlaying) {
      // 暂停逻辑
      clearInterval(this.timerId);
    } else {
      // 播放逻辑
      this.timerId = setInterval(() => {
        if (this.currentTime < this.totalTime) {
          this.currentTime += 1;
        } else {
          clearInterval(this.timerId);
          this.isPlaying = false;
        }
      }, 1000);
    }
    this.isPlaying = !this.isPlaying;
  }

  // Slider拖动事件处理
  private onSliderChange(value: number) {
    this.currentTime = value;
    if (this.isPlaying) {
      // 如果正在播放,重启计时器保持同步
      clearInterval(this.timerId);
      this.timerId = setInterval(() => {
        if (this.currentTime < this.totalTime) {
          this.currentTime += 1;
        } else {
          clearInterval(this.timerId);
          this.isPlaying = false;
        }
      }, 1000);
    }
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.


处理三种交互场景:

  1. 自动播放时定时更新
  2. 手动拖动时即时跳转
  3. 状态切换时资源管理

3.5 完整代码

@Entry
@Component
struct MusicPlayer {
  // 状态管理
  @State currentTime: number = 0; // 当前播放时间(秒)
  @State totalTime: number = 238; // 总时长(秒)
  @State isPlaying: boolean = false; // 播放状态
  private timerId: number = 0; // 计时器ID

  // 格式化时间显示(秒转MM:SS)
  private formatTime(seconds: number): string {
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
  }

  // 播放/暂停控制
  private togglePlay() {
    if (this.isPlaying) {
      // 暂停逻辑
      clearInterval(this.timerId);
    } else {
      // 播放逻辑
      this.timerId = setInterval(() => {
        if (this.currentTime < this.totalTime) {
          this.currentTime += 1;
        } else {
          clearInterval(this.timerId);
          this.isPlaying = false;
        }
      }, 1000);
    }
    this.isPlaying = !this.isPlaying;
  }

  // Slider拖动事件处理
  private onSliderChange(value: number) {
    this.currentTime = value;
    if (this.isPlaying) {
      // 如果正在播放,重启计时器保持同步
      clearInterval(this.timerId);
      this.timerId = setInterval(() => {
        if (this.currentTime < this.totalTime) {
          this.currentTime += 1;
        } else {
          clearInterval(this.timerId);
          this.isPlaying = false;
        }
      }, 1000);
    }
  }

  build() {
    Column() {
      // 歌曲信息
      Text('晴天 - 周杰伦')
        .fontSize(20)
        .margin({ bottom: 20 });

      // 进度条
      Slider({
        value: this.currentTime,
        min: 0,
        max: this.totalTime,
        step: 1,
        style: SliderStyle.OutSet // 进度条样式
      })
        .blockColor(Color.Blue) // 滑块颜色
        .trackColor(Color.Gray) // 背景轨道颜色
        .selectedColor(Color.Blue) // 进度颜色
        .showSteps(false) // 隐藏步进点
        .onChange((value: number) => { // 拖动事件
          this.onSliderChange(value);
        })
        .width('90%')

      // 时间显示
      Row() {
        Text(this.formatTime(this.currentTime))
          .fontColor(Color.Black)

        Blank() // 空白填充

        Text(this.formatTime(this.totalTime))
          .fontColor(Color.Gray)
      }
      .width('90%')
      .margin({ top: 8 })

      // 控制按钮
      Row() {
        Button(this.isPlaying ? '⏸️' : '▶️') // 播放/暂停按钮
          .onClick(() => this.togglePlay())
          .backgroundColor(Color.Transparent)
          .fontSize(32)

        Button('⏹️') // 停止按钮
          .onClick(() => {
            this.currentTime = 0;
            clearInterval(this.timerId);
            this.isPlaying = false;
          })
          .backgroundColor(Color.Transparent)
          .fontSize(32)
          .margin({ left: 20 })
      }
      .margin({ top: 20 })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor(Color.White)
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.

收藏
回复
举报
1
1条回复
按时间正序
/
按时间倒序
鸿蒙活动小助手
鸿蒙活动小助手

抓住新人~修改个头像和昵称,会更赞哦~

回复
2025-3-14 17:23:09


回复
    相关推荐