往期鸿蒙全套实战精彩文章必看内容:
- 鸿蒙开辟焦点知识点,看这篇文章就够了
- 最新版!鸿蒙HarmonyOS Next应用开辟实战学习路线
- 鸿蒙HarmonyOS NEXT开辟技能最全学习路线指南
- 鸿蒙应用开辟实战项目,看这一篇文章就够了(部分项目附源码)
前次写过一次鸿蒙的音乐项目,不过是基于api9,最近幽蓝君把它完善优化,并适配到api 12,也就是最新的鸿蒙NEXT版本,供各人参考。
先来看这次音乐播放器项目的效果图:
下面为各人详解一下这个项目。
探索发现
这是个简单的音乐列表页,从全局看,有导航栏说明要用Navigation组件,当然也可以自界说,导航栏部分还有个切换开关,可以使用menu实现:相干代码如下:
- @Builder NavigationMenu(){ Row({space:10}){ Text('探索') .fontColor(Color.Black) .fontSize(15) Row() .width(1) .height(18) .backgroundColor(Color.Gray) Text('推荐') .fontColor(Color.Gray) .fontSize(15) } .width('100%') .justifyContent(FlexAlign.Center) .height(50) .alignItems(VerticalAlign.Center) } Navigation(){ //内容部分 } .titleMode(NavigationTitleMode.Mini) .hideBackButton(true) .width('100%') .height('100%') .backgroundColor('rgba(245, 245, 245, 1)') .menus(this.NavigationMenu())
复制代码 然后,内容部分显然使用List组件实现,可以看到它可以分为3部分,分别是搜索框、今日热歌和歌单遨游指南。前两个部分都比较简单,歌单遨游指南是可以左右滑动的,所以我使用网格组件Grid实现,设置rowsTemplate属性可以使Grid水平方向滑动,相干代码如下:
- ListItemGroup({header:this.SectionHeader('歌单遨游指南',false)}){
- ListItem(){
- Grid(){
- ForEach(this.albumList,(item:Album,index)=>{
- GridItem(){
- Column(){
- Image(item.cover)
- .width(150)
- .height(150)
- Text(item.title)
- .fontColor(Color.Black)
- .fontSize(15)
- .fontWeight(FontWeight.Bold)
- .margin({top:5})
- .maxLines(2)
- }
- .alignItems(HorizontalAlign.Center)
- .width(150)
- .height(200)
- }
- })
- }
- .width('100%')
- .rowsTemplate('1fr 1fr')
- .rowsGap(12)
- .columnsGap(10)
- .padding({left:12})
- .margin({top:5})
- .scrollBarWidth(0)
- }
- .height(400)
- }
复制代码 播放音乐页面
这个页面看起来很复杂,其实并不难。这里幽蓝君想说的是,布局无非三种方式,横向、竖向和层叠,其他的布局方式都由这三种衍生而来。
所以对于这个界面,只要把它拆分开来就会发现其实很容易:
有一点难度的地方就是中间的图片是旋转的,我们给他设置一个动态的角度,使用定时器控制图片旋转,代码如下:
- Image($rawfile(this.musicList[this.currentIndex].cover))
- .width(this.screenWidth - 50)
- .height(this.screenWidth - 50)
- .borderRadius((this.screenWidth - 50)/2)
- .objectFit(ImageFit.Fill)
- .rotate({ x: 0, y: 0, z: 1, angle: this.value*360 })
-
- this.timer = setInterval(() => {
- // 保留2位小数
- this.value = this.value + 0.005
- }, 30);
复制代码 还有一个地方要说一下,点击列表按钮会弹出一个音乐列表,这里使用bindsheet实现,难倒不难,就是有很多友友不知道这个东西:

相干代码如下:
- Column(){
- }
- .bindSheet($$this.showList, this.listPage(), {
- height: 40 + (58 + 5)*this.musicList.length,
- backgroundColor: Color.White,
- showClose:false,
- })
- @Builder listPage(){
- Column(){
- Divider()
- .width('100%')
- .height(0.8)
- .backgroundColor('rgb(226,226,226)')
- List({space:0}){
- ForEach(this.musicList,(item:Music,index)=>{
- ListItem(){
- Row(){
- Column(){
- Text(item.name)
- .fontColor('#222628')
- .fontSize(16)
- }
- .alignItems(HorizontalAlign.Start)
- if(this.currentIndex == index && this.isPlay){
- Image($r('app.media.list_pause'))
- .width(28)
- .height(28)
- .onClick(()=>{
- this.playOrPause()
- })
- }else{
- Image($r('app.media.list_play'))
- .width(28)
- .height(28)
- .onClick(()=>{
- this.playSong(index)
- })
- }
- }
- .alignItems(VerticalAlign.Center)
- .justifyContent(FlexAlign.SpaceBetween)
- .width('100%')
- .height(62)
- }
- })
- }
- .divider({strokeWidth:0.5,color:'rgb(236,236,236)'})
- .padding({left:20,right:20})
- }
- .expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.BOTTOM])
- .alignItems(HorizontalAlign.Start)
- .width('100%')
- .backgroundColor(Color.White)
- .borderRadius({topLeft:20,topRight:20})
- .shadow({ radius: 30, color: 'rgba(230,230,230,0.7)', offsetX: 0, offsetY: -20 })
- }
复制代码 播放音乐
这个项目中使用本地音乐文件,所以跟各人分享下播放本地的音频文件。起首把文件放到rawfile文件夹中,播放音乐的代码如下:
- // 创建avPlayer实例对象
- let avPlayer: media.AVPlayer = await media.createAVPlayer();
- // 创建状态机变化回调函数
- this.setAVPlayerCallback(avPlayer);
- // 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址
- // 返回类型为{fd,offset,length},fd为HAP包fd地址,offset为媒体资源偏移量,length为播放长度
- let context = getContext(this) as common.UIAbilityContext;
- let fileDescriptor = await context.resourceManager.getRawFd(this.musicList[this.currentIndex].url);
- let avFileDescriptor: media.AVFileDescriptor =
- { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length };
- this.isSeek = false; // 支持seek操作
- // 为fdSrc赋值触发initialized状态机上报
- avPlayer.fdSrc = avFileDescriptor;
- this.avPlayer = avPlayer
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |