目录
PlayPage效果图:
1.从Index跳转到playPage
src/main/ets/pages/Index.ets:
// 播放歌曲信息后面完成
Row() {
Row({ space: 10 }) {
Image(this.img)
.height(50)
Column() {
Text(this.name)
.width('100%')
.fontColor(Color.White)
Text(this.author)
.width('100%')
.fontColor(Color.White)
.fontSize(12)
}
}
.padding({ left: 10 })
.layoutWeight(2)
.height('100%')
Row() {
// 上一首
Image($r('app.media.ic_prev'))
.height(25)
.fillColor('#4bb0c4')
.onClick(() => {
AvPlayerManager.pre()
})
if (this.isplaying == false) {
/*播放按钮*/
Image($r('app.media.ic_play'))
.height(25)
.fillColor('#4bb0c4')
.onClick(() => {
AvPlayerManager.reWork()
//将isplaying状态变量的值改为 true
this.isplaying = true
})
}
if (this.isplaying == true) {
// 暂停按钮
Image($r('app.media.ic_paused'))
.height(25)
.fillColor('#4bb0c4')
.onClick(() => {
// 对播放对象发出一个暂停的指令
AvPlayerManager.pause()
// 将isplaying状态变量的值改为false
this.isplaying = false
})
}
// 下一首
Image($r('app.media.ic_next'))
.height(25)
.fillColor('#4bb0c4')
.onClick(() => {
AvPlayerManager.next()
})
}
.justifyContent(FlexAlign.SpaceBetween)
.layoutWeight(1)
.height('100%')
}
.backgroundColor(Color.Black)
.height(60)
.margin({ bottom: 55 })
.onClick(() => {
// 跳转到playPage页面去
// 注意:pushUrl跳转的页面是可以返回的(没有被覆盖的,还在内存中),replaceUrl跳转的页面是会被覆盖的,不能再返回的
router.pushUrl({ url:'pages/playPage'})
})
实现的主要代码是:
router.pushUrl({ url:'pages/playPage'})
增加onclick属性,使用router.pushUrl导航的方法,添加url地址,就可以实现点击播放栏跳转到PlayPage页面。
2.PlayPage静态结构
src/main/ets/pages/playPage.ets:
import { AvPlayerManager, songItemType } from '../services/AvPlayerManager'
@Entry
@Component
struct PlayPage {
@State angle: number = 0
build() {
Column() {
// CD唱片
Stack() {
Image($r('app.media.ic_cd'))
.height(300)
.borderRadius(300)
Image('http://yjy-teach-oss.oss-cn-beijing.aliyuncs.com/HeimaCloudMusic/3.jpg')
.height(200)
.borderRadius(200)
}
// 歌曲信息
Column({space:5}) {
Text('奢香夫人')
.fontSize(25)
.fontWeight(800)
.fontColor(Color.White)
Text('凤凰传奇')
.fontSize(15)
.fontColor(Color.White)
}
.width('100%')
// 播放进度+控制按钮容器
Column() {
// 播放进度
Row({ space: 5 }) {
Text('00:00') // 当前进度时间
.fontColor(Color.White)
Slider()
.layoutWeight(1)
Text('00:00') //歌曲总时间
.fontColor(Color.White)
}
.padding({ left: 10, right: 10,bottom:20 })
// 控制按钮
Row() {
Image($r('app.media.ic_repeat'))
.width(30)
Image($r('app.media.ic_prev'))
.width(30)
.fillColor(Color.White)
Image($r('app.media.ic_play'))
.width(45)
.fillColor(Color.White)
Image($r('app.media.ic_next'))
.width(30)
.fillColor(Color.White)
Image($r('app.media.ic_song_list'))
.fillColor(Color.White)
.width(30)
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({bottom:-30})
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
.justifyContent(FlexAlign.SpaceAround)
.height('100%')
.width('100%')
// 线性渐变
.linearGradient({
angle: 180, // 颜色从上往下变化
colors: [ // 渐变颜色数组
['#7f797a', 0.1], //灰色
['#b43038', 0.5], // 红色
['#b43038', 0.8], // 红色
['#b43038', 1], // 红色
]
})
}
}
简单的静态结构布局,调整好属性值,因为没有标准的参数,看着接近就行,想要精准,可以拿绘图软件工具测量。
3.CD动画实现
src/main/ets/pages/playPage.ets:
@State angle: number = 0 // 控制角度变化值 0 - 360度改变
// CD唱片
Stack() {
Image($r('app.media.ic_cd'))
.height(300)
.borderRadius(300)
Image('http://yjy-teach-oss.oss-cn-beijing.aliyuncs.com/HeimaCloudMusic/3.jpg')
.height(200)
.borderRadius(200)
}
// 控制一个元素旋转
.rotate({angle:this.angle})
// 元素加载完毕之后触发一个回调函数 .onAppear
.onAppear(()=>{
this.angle = 360 //将角度改成360都
})
// 增加旋转的动画效果
.animation({
duration:10000, // 用10秒钟的时间让元素旋转一圈
curve:Curve.Linear, // 匀速旋转
iterations:-1 //表示设置旋转的圈数,如果是-1则表示不停的转,如果是正数则表示转的圈数
})
设置参数,控制角度变化值 0 - 360度改变:
@State angle: number = 0
.rotate属性控制唱针的角度,元素加载完毕之后触发一个回调函数 .onAppear,之后增加旋转效果:
// 控制一个元素旋转
.rotate({angle:this.angle})
// 元素加载完毕之后触发一个回调函数 .onAppear
.onAppear(()=>{
this.angle = 360 //将角度改成360都
})
.animation({
duration:10000, // 用10秒钟的时间让元素旋转一圈
curve:Curve.Linear, // 匀速旋转
iterations:-1 //表示设置旋转的圈数,如果是-1则表示不停的转,如果是正数则表示转的圈数
})
4.播放进度动态化
import { AvPlayerManager, songItemType } from '../services/AvPlayerManager'
@Entry
@Component
struct PlayPage {
@State angle: number = 0 // 控制角度变化值 0 - 360度改变
@State totalTime: number = 0
@State currentTime: number = 0
aboutToAppear() {
this.totalTime = AvPlayerManager.avPlayer.duration // 表示当前正在播放歌曲的总时间,单位是毫秒
// 不停的获取当前歌曲的已播放时长
AvPlayerManager.avPlayer.on('timeUpdate', (time) => {
// time表示当前歌曲已经播放的时长,单位是毫秒
this.currentTime = time
})
}
build() {
Column() {
// CD唱片
Stack() {
Image($r('app.media.ic_cd'))
.height(300)
.borderRadius(300)
Image(AvPlayerManager.songs[AvPlayerManager.index].img)
.height(200)
.borderRadius(200)
}
// 控制一个元素旋转 (这个属性一定要写在animation前面,否则不会触发动画)
.rotate({ angle: this.angle })
// 元素加载完毕之后触发一个回调函数 .onAppear
.onAppear(() => {
this.angle = 360 //将角度改成360都
})
// 增加旋转的动画效果
.animation({
duration: 10000, // 用10秒钟的时间让元素旋转一圈
curve: Curve.Linear, // 匀速旋转
iterations: -1 //表示设置旋转的圈数,如果是-1则表示不停的转,如果是正数则表示转的圈数
})
// 歌曲信息
Column({ space: 5 }) {
Text(AvPlayerManager.songs[AvPlayerManager.index].name)
.fontSize(25)
.fontWeight(800)
.fontColor(Color.White)
Text(AvPlayerManager.songs[AvPlayerManager.index].author)
.fontSize(15)
.fontColor(Color.White)
}
.width('100%')
// 播放进度+控制按钮容器
Column() {
// 播放进度
Row({ space: 5 }) {
Text(this.currentTime.toString()) // 当前进度时间
.fontColor(Color.White)
Slider({
min:0,
max:this.totalTime,
value:this.currentTime
})
.layoutWeight(1)
Text(this.totalTime.toString()) //歌曲总时间
.fontColor(Color.White)
}
.padding({ left: 10, right: 10, bottom: 20 })
// 控制按钮
Row() {
Image($r('app.media.ic_repeat'))
.width(30)
Image($r('app.media.ic_prev'))
.width(30)
.fillColor(Color.White)
Image($r('app.media.ic_play'))
.width(45)
.fillColor(Color.White)
Image($r('app.media.ic_next'))
.width(30)
.fillColor(Color.White)
Image($r('app.media.ic_song_list'))
.fillColor(Color.White)
.width(30)
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({ bottom: -30 })
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
.justifyContent(FlexAlign.SpaceAround)
.height('100%')
.width('100%')
// 线性渐变
.linearGradient({
angle: 180, // 颜色从上往下变化
colors: [ // 渐变颜色数组
['#7f797a', 0.1], //灰色
['#b43038', 0.5], // 红色
['#b43038', 0.8], // 红色
['#b43038', 1], // 红色
]
})
}
}
实现包括:
定义变量totalTime、totalTime, aboutToAppear()方法内把当前歌曲总时间赋值给totalTime,之后再不停获取歌曲当前已播放时间。
@State totalTime: number = 0
@State totalTime: number = 0aboutToAppear() {
this.totalTime = AvPlayerManager.avPlayer.duration // 表示当前正在播放歌曲的总时间,单位是毫秒// 不停的获取当前歌曲的已播放时长
AvPlayerManager.avPlayer.on('timeUpdate', (time) => {
// time表示当前歌曲已经播放的时长,单位是毫秒
this.currentTime = time
})
}
在Slider内增加max:this.totalTime、value:this.currentTime,实现进度条不停显示当前时间和总时间。
Text(this.currentTime.toString()) // 当前进度时间
.fontColor(Color.White)Slider({
min:0,
max:this.totalTime,
value:this.currentTime
})
.layoutWeight(1)Text(this.totalTime.toString()) //歌曲总时间
5.播放进度时间格式化
将毫秒时间格式改为分秒格式。
import { AvPlayerManager, songItemType } from '../services/AvPlayerManager'
@Entry
@Component
struct PlayPage {
@State angle: number = 0 // 控制角度变化值 0 - 360度改变
@State totalTime: number = 0
@State currentTime: number = 0
aboutToAppear() {
this.totalTime = AvPlayerManager.avPlayer.duration // 表示当前正在播放歌曲的总时间,单位是毫秒
// 不停的获取当前歌曲的已播放时长
AvPlayerManager.avPlayer.on('timeUpdate', (time) => {
// time表示当前歌曲已经播放的时长,单位是毫秒
this.currentTime = time
})
}
// 作用:接收一个毫秒数值,转成成 00:00这种格式的字符串返回
formatTime(time: number) {
// 1. 计算出分钟数
let seconds = time / 1000 //将毫秒数转成总秒数
let min = Math.floor(seconds / 60) // 获取到了分钟部分
// 2. 计算出除开分钟之外的剩余的秒数
let s = Math.ceil(seconds % 60) // Math.ceil(19.89) -> 20
return `${min.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`
}
build() {
Column() {
// CD唱片
Stack() {
Image($r('app.media.ic_cd'))
.height(300)
.borderRadius(300)
Image(AvPlayerManager.songs[AvPlayerManager.index].img)
.height(200)
.borderRadius(200)
}
// 控制一个元素旋转 (这个属性一定要写在animation前面,否则不会触发动画)
.rotate({ angle: this.angle })
// 元素加载完毕之后触发一个回调函数 .onAppear
.onAppear(() => {
this.angle = 360 //将角度改成360都
})
// 增加旋转的动画效果
.animation({
duration: 10000, // 用10秒钟的时间让元素旋转一圈
curve: Curve.Linear, // 匀速旋转
iterations: -1 //表示设置旋转的圈数,如果是-1则表示不停的转,如果是正数则表示转的圈数
})
// 歌曲信息
Column({ space: 5 }) {
Text(AvPlayerManager.songs[AvPlayerManager.index].name)
.fontSize(25)
.fontWeight(800)
.fontColor(Color.White)
Text(AvPlayerManager.songs[AvPlayerManager.index].author)
.fontSize(15)
.fontColor(Color.White)
}
.width('100%')
// 播放进度+控制按钮容器
Column() {
// 播放进度
Row({ space: 5 }) {
Text(this.formatTime(this.currentTime)) // 当前进度时间
.fontColor(Color.White)
Slider({
min: 0,
max: this.totalTime,
value: this.currentTime
})
.layoutWeight(1)
Text(this.formatTime(this.totalTime)) //歌曲总时间
.fontColor(Color.White)
}
.padding({ left: 10, right: 10, bottom: 20 })
// 控制按钮
Row() {
Image($r('app.media.ic_repeat'))
.width(30)
Image($r('app.media.ic_prev'))
.width(30)
.fillColor(Color.White)
Image($r('app.media.ic_play'))
.width(45)
.fillColor(Color.White)
Image($r('app.media.ic_next'))
.width(30)
.fillColor(Color.White)
Image($r('app.media.ic_song_list'))
.fillColor(Color.White)
.width(30)
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({ bottom: -30 })
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
.justifyContent(FlexAlign.SpaceAround)
.height('100%')
.width('100%')
// 线性渐变
.linearGradient({
angle: 180, // 颜色从上往下变化
colors: [ // 渐变颜色数组
['#7f797a', 0.1], //灰色
['#b43038', 0.5], // 红色
['#b43038', 0.8], // 红色
['#b43038', 1], // 红色
]
})
}
}
主要转换代码:
formatTime(time: number) {
// 1. 计算出分钟数
let seconds = time / 1000 //将毫秒数转成总秒数
let min = Math.floor(seconds / 60) // 获取到了分钟部分// 2. 计算出除开分钟之外的剩余的秒数
let s = Math.ceil(seconds % 60) // Math.ceil(19.89) -> 20return `${min.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`
}
之后设置Text(this.formatTime(this.currentTime))、Text(this.formatTime(this.totalTime)) 赋值,
标签:app,鸿蒙,Color,Image,AvPlayerManager,width,White,黑马,页面 From: https://blog.csdn.net/m0_74748236/article/details/141808135Row({ space: 5 }) {
Text(this.formatTime(this.currentTime)) // 当前进度时间
.fontColor(Color.White)Slider({
min: 0,
max: this.totalTime,
value: this.currentTime
})
.layoutWeight(1)Text(this.formatTime(this.totalTime)) //歌曲总时间
.fontColor(Color.White)
}