HarmonyOS鸿蒙Next中使用ArkUI eTS实现仿网易云音乐播放器界面
HarmonyOS鸿蒙Next中使用ArkUI eTS实现仿网易云音乐播放器界面
介绍
学习鸿蒙eTS有一段时间了,最近仿照网易云音乐写了一个音乐播放器,感觉eTS学起来还是很容易上手的,有些地方可能写的不大好,请多多指教。效果图如下:
说明
目前仅仅完整了UI界面和动画效果,等有时间了搞一下音乐播放的功能。还有就是没真机,模拟器播放音乐听不到声音,等下次把播放音乐的功能完成了,希望哪个大佬能用真机帮我测试下,哈哈哈
Demo实现
我把界面划分成了四个部分来实现的:标题组件(TitleCpt)、转盘组件(DiskCpt)、互动组件(ActionCpt)以及音乐控制组件(CtrlCpt),代码如下:
@Entry
@Component
struct PlayPage {
[@State](/user/State) diskAngle: number = 0
[@State](/user/State) styliAngle: number = 30
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
TitleCpt()
DiskCpt({ diskAngle: $diskAngle, styliAngle: $styliAngle })
ActionCpt()
CtrlCpt({ diskAngle: $diskAngle, styliAngle: $styliAngle })
}
.width('100%')
.height('100%')
.padding({ left: 16, right: 16 })
.backgroundImage('./common/bg.jpg')
.backgroundImageSize({ width: 1280, height: 2340 })
}
}
1、标题组件(TitleCpt)实现:
@Component
export default struct TitleCpt {
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
Image($r('app.media.cyc')).height(50).width(50)
Column() {
Text('真的爱你').fontColor(Color.White).fontSize(20)
Text('Beyond').fontColor(Color.White).fontSize(15)
}
Image($r("app.media.ic_share")).height(50).width(50)
}
.height(60)
}
}
2、转盘组件(DiskCpt)实现:
@Component
export default struct DiskCpt {
[@Link](/user/Link) diskAngle: number
[@Link](/user/Link) styliAngle: number
build() {
Stack({ alignContent: Alignment.Top }) {
Stack({ alignContent: Alignment.Center }) {
Image($r('app.media.f63')).height(300).width(300)
Image($r('app.media.dog')).height(200).width(200)
Image($r('app.media.pic_disc')).height(300).width(300)
}.margin({ top: 100 })
.rotate({ x: 0, y: 0, z: 1, angle: this.diskAngle })
Stack() {
Image($r('app.media.pic_styli')).height(185).width(101).margin({ left: 70 })
}
.rotate({ x: 0, y: 0, z: 1,
angle: -this.styliAngle,
centerX: '50%',
centerY: 0
})
}
.layoutWeight(1)
.padding({ top: 40 })
}
}
3、互动组件(ActionCpt)实现:
@Component
export default struct ActionCpt {
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) {
Image($r("app.media.ic_love")).height(50).width(50)
Image($r("app.media.ic_download")).height(50).width(50)
Image($r("app.media.ic_comment")).height(50).width(50)
Image($r("app.media.ic_more")).height(50).width(50)
}
}
}
4、音乐控制组件(CtrlCpt)实现:
@Component
export default struct CtrlCpt {
[@State](/user/State) sliderValue: number = 40
[@State](/user/State) playImage: string= './common/ic_play.png'
[@Link](/user/Link) diskAngle: number
[@Link](/user/Link) styliAngle: number
private interval: number = 0
startDiskRotate() {
this.interval = setInterval(() => {
this.diskAngle += 1
}, 10)
}
stopDiskRotate() {
setTimeout(() => {
clearInterval(this.interval)
}, 600)
}
startStyli() {
animateTo({
duration: 600, // 动画时长
curve: Curve.Smooth, // 动画曲线
}, () => {
this.styliAngle = 0
})
}
stopStyli() {
animateTo({
duration: 600, // 动画时长
tempo: 0.5, // 播放速率
curve: Curve.Smooth, // 动画曲线
}, () => {
this.styliAngle = 30
})
}
build() {
Column() {
Row() {
Text('01:10').fontColor('#cccccc').fontSize(15)
Slider({
value: this.sliderValue, min: 0, max: 100, step: 1,
style: SliderStyle.OutSet
})
.blockColor(Color.White)
.trackColor('#cccccc')
.selectedColor(Color.White)
.showTips(false)
.layoutWeight(1)
.onChange((value: number, mode: SliderChangeMode) => {
this.sliderValue = value
console.info('value:' + value + 'mode:' + mode.toString())
})
Text('01:10').fontColor('#cccccc').fontSize(15)
}
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
Image($r("app.media.ic_play_mode")).height(50).width(50)
Row() {
Image($r("app.media.ic_play_pre")).height(50).width(50)
Image(this.playImage).height(50).width(50)
.onClick(() => {
if (this.playImage === './common/ic_play.png') {
this.playImage = './common/ic_pause.png'
this.startDiskRotate()
this.startStyli()
} else {
this.playImage = './common/ic_play.png'
this.stopDiskRotate()
this.stopStyli()
}
})
Image($r("app.media.ic_play_next")).height(50).width(50)
}
Image($r("app.media.ic_play_list")).height(50).width(50)
}
.padding({ bottom: 16 })
}
}
}
总结
开发过程中遇到的问题主要有两个:
- 兄弟组件传值的问题,使用@State和@Link解决了兄弟组件之间数据的双向绑定问题
- 动画问题,找了半天没找到那种可以手动开始和暂停的动画方案,最后参考Codela《基础组件Slider的使用(eTS)》,使用setInterval来实现的动画。
更多关于HarmonyOS鸿蒙Next中使用ArkUI eTS实现仿网易云音乐播放器界面的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2022年就写的这么好了,偶像啊
更多关于HarmonyOS鸿蒙Next中使用ArkUI eTS实现仿网易云音乐播放器界面的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
后台播放如何做呢?
楼主找到手动启停动画的方法了吗
学习一下
666
希望HarmonyOS能加强与其他品牌设备的兼容性,让更多人受益。
棒棒的,论坛目前有一个Codelabs挑战赛期待您的参加:
https://developer.huawei.com/consumer/cn/forum/topic/0201877679236150031?fid=0101271690375130218
我上一个帖子怎么没人邀请我参加,
在HarmonyOS鸿蒙Next中,使用ArkUI eTS实现仿网易云音乐播放器界面,可以通过以下步骤进行:
-
项目创建:首先在DevEco Studio中创建一个新的ArkUI eTS项目。
-
界面布局:使用ArkUI的组件进行界面布局。主要组件包括
Column
、Row
、Stack
、Flex
等。播放器界面可以分为顶部导航栏、音乐封面、播放控制栏、歌词显示区等部分。 -
顶部导航栏:使用
Row
组件实现,包含返回按钮、标题和更多操作按钮。可以使用Image
组件加载图标,Text
组件显示标题。 -
音乐封面:使用
Image
组件加载音乐封面图片,可以使用Stack
组件将封面图片和播放进度条叠加显示。 -
播放控制栏:使用
Row
组件实现,包含播放/暂停按钮、上一首、下一首按钮、播放进度条和音量控制。可以使用Slider
组件实现进度条和音量控制。 -
歌词显示区:使用
Scroll
组件实现歌词的滚动显示,Text
组件显示歌词内容。可以通过动态更新Text
组件的内容实现歌词的同步显示。 -
状态管理:使用
@State
、@Prop
、@Link
等装饰器管理组件的状态。例如,播放/暂停按钮的状态、播放进度、当前歌词等。 -
事件处理:为按钮、滑动条等组件绑定事件处理函数,实现播放、暂停、切换歌曲、调整音量等功能。
-
样式美化:使用ArkUI的样式系统对界面进行美化,包括颜色、字体、间距等。
-
测试与调试:在模拟器或真机上运行项目,测试界面的显示效果和交互功能,进行必要的调试和优化。
通过以上步骤,可以在HarmonyOS鸿蒙Next中使用ArkUI eTS实现一个仿网易云音乐的播放器界面。
在HarmonyOS鸿蒙Next中,使用ArkUI eTS实现仿网易云音乐播放器界面,可以通过以下步骤进行:
-
布局设计:使用
Flex
或Column
、Row
等布局组件构建整体结构,如顶部导航栏、音乐播放控制栏、歌曲列表等。 -
组件使用:利用
Text
、Image
、Button
等基础组件展示歌曲信息、专辑封面和播放控制按钮。 -
样式定制:通过
@Styles
或@Extend
定义样式,统一界面风格,如字体、颜色、间距等。 -
交互实现:使用
@State
、@Link
等状态管理机制,实现播放、暂停、切歌等交互功能。 -
动画效果:通过
Animation
组件为播放进度条、专辑封面旋转等添加动画效果,提升用户体验。 -
数据绑定:使用
@Observed
和@ObjectLink
实现数据与UI的绑定,动态更新歌曲信息。
通过这些步骤,可以高效地实现一个功能丰富、界面美观的仿网易云音乐播放器。