暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

99.[HarmonyOS NEXT 实战案例:音乐播放器] 基础篇 - 水平分割布局打造音乐播放器界面

原创 若城 2025-06-09
104

[HarmonyOS NEXT 实战案例:音乐播放器] 基础篇 - 水平分割布局打造音乐播放器界面

项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star

效果演示

引言

在移动应用开发中,音乐播放器是一个经典的应用场景。一个好的音乐播放器界面不仅需要美观,还需要功能区域划分清晰,操作便捷。本教程将详细讲解如何使用HarmonyOS NEXT的RowSplit组件构建一个音乐播放器界面,通过水平分割布局将界面分为专辑封面区域和播放控制区域。

组件概述

在本案例中,我们将使用以下HarmonyOS NEXT组件:

组件名称 功能描述
RowSplit 水平分割布局容器,将界面分为上下两部分
Column 垂直布局容器,用于垂直排列子组件
Row 水平布局容器,用于水平排列子组件
Image 图片组件,用于显示专辑封面
Text 文本组件,用于显示歌曲名称、歌手和时间
Button 按钮组件,用于播放控制和其他操作
Slider 滑块组件,用于进度条和音量控制

代码实现

组件结构

首先,我们定义了一个名为MusicPlayerExample的自定义组件:

@Component export struct MusicPlayerExample { @State isPlaying: boolean = false @State currentTime: number = 0 @State totalTime: number = 240 // 4分钟 build() { // 组件内容 } }

在这个组件中,我们定义了三个状态变量:

  • isPlaying:表示当前是否正在播放音乐
  • currentTime:表示当前播放时间(秒)
  • totalTime:表示音乐总时长(秒)

外层容器

我们使用Column组件作为最外层容器,包含标题文本和主要内容区域:

Column() { Text('音乐播放器布局') .fontSize(20) .fontWeight(FontWeight.Bold) .margin({ bottom: 10 }) RowSplit() { // RowSplit内容 } .height(400) } .padding(15)

外层Column设置了15的内边距,确保整个界面与屏幕边缘有适当的间距。

水平分割布局

我们使用RowSplit组件将界面分为上下两部分:

RowSplit() { // 专辑封面区域 Column() { // 专辑封面区域内容 } .height('60%') .justifyContent(FlexAlign.Center) .backgroundColor('#f8f9fa') // 播放控制区域 Column() { // 播放控制区域内容 } .padding(10) } .height(400)

在这个RowSplit中:

  1. 上部区域是专辑封面区域,占总高度的60%,背景色为浅灰色,内容居中对齐
  2. 下部区域是播放控制区域,设置了10的内边距
  3. 整个RowSplit的高度设置为400像素

专辑封面区域

专辑封面区域包含专辑图片、歌曲名称、歌手名称以及喜欢和分享按钮:

Column() { Image($r('app.media.big29')) .width(200) .height(200) .borderRadius(10) .margin({ top: 20 }) Text('夏日记忆') .fontSize(18) .margin({ top: 10 }) Text('林小夏') .fontSize(16) .margin({ top: 5 }) .fontColor('#666') // 喜欢和分享按钮 Row() { Button($r('app.media.01')) .width(24) .height(24) .backgroundColor(Color.Transparent) Button($r('app.media.02')) .width(24) .height(24) .backgroundColor(Color.Transparent) .margin({ left: 20 }) } .margin({ top: 15 }) } .height('60%') .justifyContent(FlexAlign.Center) .backgroundColor('#f8f9fa')

在这个区域中:

  1. 专辑封面图片宽高均为200像素,设置了10像素的圆角和20像素的上边距
  2. 歌曲名称使用18像素的字体大小,设置了10像素的上边距
  3. 歌手名称使用16像素的字体大小,设置了5像素的上边距,字体颜色为灰色
  4. 喜欢和分享按钮使用Row组件水平排列,每个按钮宽高均为24像素,背景色透明

播放控制区域

播放控制区域包含进度条、播放控制按钮和音量控制:

Column() { // 进度条 Row() { Text(this.formatTime(this.currentTime)) .fontSize(14) .width(50) Slider({ value: this.currentTime, min: 0, max: this.totalTime, style: SliderStyle.OutSet }) .onChange((value: number) => { this.currentTime = value }) .width('70%') Text(this.formatTime(this.totalTime)) .fontSize(14) .width(50) } .width('90%') .margin({ top: 20, bottom: 10 }) // 播放控制按钮 Row() { Button($r('app.media.03')) .width(32) .height(32) .backgroundColor(Color.Transparent) Button(this.isPlaying ? $r('app.media.04') : $r('app.media.05')) .width(40) .height(40) .backgroundColor(Color.Transparent) .margin({ left: 20, right: 20 }) .onClick(() => { this.isPlaying = !this.isPlaying }) Button($r('app.media.01')) .width(32) .height(32) .backgroundColor(Color.Transparent) } .margin({ top: 10 }) // 音量和其他控制 Row() { Button($r('app.media.02')) .width(24) .height(24) .backgroundColor(Color.Transparent) Slider({ value: 80, min: 0, max: 100, style: SliderStyle.OutSet }) .width(100) .margin({ left: 10 }) Button($r('app.media.03')) .width(24) .height(24) .backgroundColor(Color.Transparent) .margin({ left: 15 }) } .margin({ top: 20 }) } .padding(10)

在这个区域中:

  1. 进度条区域包含当前时间文本、进度滑块和总时间文本,宽度为父容器的90%
  2. 播放控制按钮区域包含上一曲、播放/暂停和下一曲按钮,播放/暂停按钮根据isPlaying状态显示不同的图标
  3. 音量控制区域包含音量图标、音量滑块和其他控制按钮

时间格式化函数

为了将秒数转换为分:秒格式,我们定义了一个formatTime方法:

private formatTime(seconds: number): string { const mins = Math.floor(seconds / 60) const secs = Math.floor(seconds % 60) return `${mins}:${secs < 10 ? '0' + secs : secs}` }

这个方法将秒数转换为分:秒格式,并确保秒数小于10时前面补0。

布局分析

水平分割的应用

在本案例中,我们使用RowSplit组件将界面分为上下两部分:

  1. 上部区域(专辑封面区域)

    • 占总高度的60%
    • 包含专辑封面、歌曲信息和操作按钮
    • 内容居中对齐,背景色为浅灰色
  2. 下部区域(播放控制区域)

    • 占总高度的40%(隐式设置)
    • 包含进度条、播放控制按钮和音量控制
    • 设置了内边距,确保内容与边缘有适当的间距

这种水平分割的布局方式非常适合音乐播放器界面,使得用户可以清晰地看到专辑封面和歌曲信息,同时方便地操作播放控制。

状态管理

在本案例中,我们使用@State装饰器定义了三个状态变量:

  1. isPlaying:控制播放/暂停按钮的图标显示
  2. currentTime:控制进度条的当前值和当前时间文本的显示
  3. totalTime:控制进度条的最大值和总时间文本的显示

当用户点击播放/暂停按钮时,isPlaying状态会切换,从而改变按钮的图标。当用户拖动进度条时,currentTime状态会更新,从而改变当前时间文本的显示。

布局技巧

比例设置

在本案例中,我们使用百分比来设置专辑封面区域的高度(height('60%')),这样可以确保在不同屏幕尺寸下,专辑封面区域和播放控制区域的比例保持一致。

内容居中

我们使用justifyContent(FlexAlign.Center)属性将专辑封面区域的内容垂直居中对齐,这样可以确保在不同屏幕尺寸下,专辑封面始终位于区域的中央。

边距设置

我们为各个组件设置了适当的边距,确保界面布局美观:

  1. 外层Column设置了15的内边距,确保整个界面与屏幕边缘有适当的间距
  2. 专辑封面设置了20的上边距,确保与顶部有适当的间距
  3. 歌曲名称和歌手名称分别设置了10和5的上边距,确保文本之间有适当的间距
  4. 播放控制区域的各个部分也设置了适当的边距,确保各个控件之间有适当的间距

总结

在本教程中,我们学习了如何使用HarmonyOS NEXT的RowSplit组件构建一个音乐播放器界面。通过水平分割布局,我们将界面分为专辑封面区域和播放控制区域,使得界面结构清晰,功能区域划分明确。

我们还学习了如何使用@State装饰器管理组件状态,如何使用Slider组件实现进度条和音量控制,以及如何使用onClick事件处理用户交互。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论