news 2026/4/11 15:25:06

Flutter for OpenHarmony音乐播放器App实战14:专辑详情实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter for OpenHarmony音乐播放器App实战14:专辑详情实现

专辑详情页是展示专辑完整信息的页面,用户可以查看专辑封面、歌手信息、发行时间以及专辑内的所有歌曲。本篇文章将详细介绍如何使用CustomScrollView和Sliver组件实现一个美观实用的专辑详情页面。

页面基础结构

专辑详情页使用StatelessWidget,因为页面状态相对简单。

import'package:flutter/material.dart';import'package:get/get.dart';classAlbumDetailPageextendsStatelessWidget{finalint id;constAlbumDetailPage({super.key,requiredthis.id});

页面通过构造函数接收专辑ID,用于加载对应的专辑数据。如果需要管理收藏状态等,可以改为StatefulWidget。

CustomScrollView结构

使用CustomScrollView组合多个Sliver组件。

@overrideWidgetbuild(BuildContextcontext){returnScaffold(body:CustomScrollView(slivers:[_buildSliverAppBar(),_buildActionBar(),_buildSongList(),],),);}

CustomScrollView允许将多个Sliver组件组合在一起滚动。页面包含三个部分:可折叠的头部、操作按钮栏和歌曲列表。

SliverAppBar头部设计

SliverAppBar实现可折叠的专辑信息头部。

Widget_buildSliverAppBar(){returnSliverAppBar(expandedHeight:300,pinned:true,flexibleSpace:FlexibleSpaceBar(background:Container(decoration:BoxDecoration(gradient:LinearGradient(begin:Alignment.topCenter,end:Alignment.bottomCenter,colors:[Colors.primaries[id%Colors.primaries.length],Colors.black,],),),

expandedHeight设置展开高度为300,pinned为true让AppBar收起后固定在顶部。背景使用渐变色,从专辑主题色过渡到黑色。

专辑封面与信息

头部展示专辑封面和基本信息。

child:SafeArea(child:Padding(padding:constEdgeInsets.all(20),child:Row(crossAxisAlignment:CrossAxisAlignment.end,children:[Container(width:150,height:150,decoration:BoxDecoration(borderRadius:BorderRadius.circular(12),color:Colors.white24,boxShadow:[BoxShadow(color:Colors.black.withOpacity(0.3),blurRadius:20,offset:constOffset(0,10),),],),child:constIcon(Icons.album,size:70,color:Colors.white70),),

封面使用圆角矩形,添加阴影增加立体感。实际项目中会使用网络图片替换Icon。

专辑文字信息

封面右侧显示专辑名称、歌手和发行时间。

constSizedBox(width:16),Expanded(child:Column(mainAxisAlignment:MainAxisAlignment.end,crossAxisAlignment:CrossAxisAlignment.start,children:[Text('专辑${id+1}',style:constTextStyle(color:Colors.white,fontSize:22,fontWeight:FontWeight.bold,),),constSizedBox(height:8),GestureDetector(onTap:()=>Get.toNamed('/artist/$id'),child:constText('歌手名称',style:TextStyle(color:Colors.white70),),),constSizedBox(height:4),Text('发行时间:${2020+id%5}年',style:constTextStyle(color:Colors.white54,fontSize:12),),],),),],),),),),),);}

歌手名称可点击跳转到歌手详情页。使用不同透明度的白色区分信息层级。

操作按钮栏

操作栏包含播放全部、收藏和分享按钮。

Widget_buildActionBar(){returnSliverToBoxAdapter(child:Padding(padding:constEdgeInsets.all(16),child:Row(children:[Expanded(child:ElevatedButton.icon(onPressed:()=>_playAll(),icon:constIcon(Icons.play_arrow),label:constText('播放全部'),style:ElevatedButton.styleFrom(backgroundColor:constColor(0xFFE91E63),foregroundColor:Colors.white,padding:constEdgeInsets.symmetric(vertical:12),shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(25),),),),),constSizedBox(width:12),IconButton(icon:constIcon(Icons.favorite_border),onPressed:()=>_toggleFavorite(),),IconButton(icon:constIcon(Icons.share),onPressed:()=>_shareAlbum(),),],),),);}

播放全部按钮使用主题色,占据大部分宽度。收藏和分享使用图标按钮,节省空间。

歌曲列表

使用SliverList构建歌曲列表。

Widget_buildSongList(){returnSliverList(delegate:SliverChildBuilderDelegate((context,index)=>_buildSongItem(index),childCount:10,),);}

SliverChildBuilderDelegate实现懒加载,只构建可见的列表项。childCount设置歌曲总数。

歌曲列表项

每首歌曲显示序号、名称、歌手和时长。

Widget_buildSongItem(int index){returnListTile(leading:Container(width:32,alignment:Alignment.center,child:Text('${index+1}',style:TextStyle(color:index<3?constColor(0xFFE91E63):Colors.grey,fontWeight:index<3?FontWeight.bold:FontWeight.normal,),),),title:Text('歌曲${index+1}',maxLines:1,overflow:TextOverflow.ellipsis,),subtitle:constText('歌手名称',style:TextStyle(color:Colors.grey,fontSize:12),),trailing:Row(mainAxisSize:MainAxisSize.min,children:[constText('04:32',style:TextStyle(color:Colors.grey,fontSize:12),),IconButton(icon:constIcon(Icons.more_vert,color:Colors.grey),onPressed:()=>_showSongOptions(index),),],),onTap:()=>_playSong(index),);}

前三首歌曲的序号使用主题色突出显示。trailing包含时长和更多操作按钮。

歌曲操作菜单

点击更多按钮显示操作菜单。

void_showSongOptions(int index){Get.bottomSheet(Container(decoration:constBoxDecoration(color:Color(0xFF1E1E1E),borderRadius:BorderRadius.vertical(top:Radius.circular(16)),),child:Column(mainAxisSize:MainAxisSize.min,children:[ListTile(leading:Container(width:50,height:50,decoration:BoxDecoration(borderRadius:BorderRadius.circular(8),color:Colors.grey.withOpacity(0.3),),child:constIcon(Icons.music_note,color:Colors.white70),),title:Text('歌曲${index+1}'),subtitle:constText('歌手名称',style:TextStyle(color:Colors.grey)),),constDivider(),ListTile(leading:constIcon(Icons.play_circle_outline),title:constText('下一首播放'),onTap:()=>Get.back(),),ListTile(leading:constIcon(Icons.playlist_add),title:constText('添加到歌单'),onTap:()=>Get.back(),),ListTile(leading:constIcon(Icons.download_outlined),title:constText('下载'),onTap:()=>Get.back(),),ListTile(leading:constIcon(Icons.share_outlined),title:constText('分享'),onTap:()=>Get.back(),),constSizedBox(height:16),],),),);}

菜单顶部显示歌曲信息,下方是各种操作选项。这种设计让用户在操作前可以确认选中的歌曲。

播放全部方法

点击播放全部按钮后播放专辑内所有歌曲。

void_playAll(){Get.toNamed('/player',arguments:{'albumId':id,'startIndex':0,});Get.snackbar('播放','开始播放专辑',snackPosition:SnackPosition.BOTTOM,);}

跳转到播放器页面,传递专辑ID和起始索引。

播放单曲方法

点击单曲后从该歌曲开始播放。

void_playSong(int index){Get.toNamed('/player',arguments:{'albumId':id,'startIndex':index,});}

传递起始索引,播放器会从该歌曲开始播放专辑。

收藏专辑方法

收藏按钮的点击处理。

void_toggleFavorite(){// 实际项目中需要调用API并更新状态Get.snackbar('收藏','已添加到收藏',snackPosition:SnackPosition.BOTTOM,);}

实际项目中需要调用API更新收藏状态,并使用状态管理更新UI。

分享专辑方法

分享按钮的点击处理。

void_shareAlbum(){Get.bottomSheet(Container(decoration:constBoxDecoration(color:Color(0xFF1E1E1E),borderRadius:BorderRadius.vertical(top:Radius.circular(16)),),child:Column(mainAxisSize:MainAxisSize.min,children:[constPadding(padding:EdgeInsets.all(16),child:Text('分享到',style:TextStyle(fontSize:18,fontWeight:FontWeight.bold)),),Row(mainAxisAlignment:MainAxisAlignment.spaceEvenly,children:[_buildShareItem(Icons.chat,'微信'),_buildShareItem(Icons.people,'朋友圈'),_buildShareItem(Icons.message,'微博'),_buildShareItem(Icons.link,'复制链接'),],),constSizedBox(height:24),],),),);}Widget_buildShareItem(IconDataicon,Stringlabel){returnGestureDetector(onTap:(){Get.back();Get.snackbar('分享','分享到$label');},child:Column(children:[Container(width:50,height:50,decoration:BoxDecoration(color:Colors.grey.withOpacity(0.3),shape:BoxShape.circle,),child:Icon(icon,color:Colors.white70),),constSizedBox(height:8),Text(label,style:constTextStyle(fontSize:12)),],),);}

分享菜单显示常用的分享渠道,点击后执行对应的分享操作。

专辑简介区域

可以在歌曲列表前添加专辑简介。

Widget_buildAlbumDescription(){returnSliverToBoxAdapter(child:Padding(padding:constEdgeInsets.all(16),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[constText('专辑简介',style:TextStyle(fontSize:16,fontWeight:FontWeight.bold),),constSizedBox(height:8),constText('这是一张非常棒的专辑,收录了歌手的多首经典作品。''专辑风格多样,既有抒情慢歌,也有动感快歌,值得细细品味。',style:TextStyle(color:Colors.grey,height:1.6),maxLines:3,overflow:TextOverflow.ellipsis,),GestureDetector(onTap:()=>_showFullDescription(),child:constText('展开',style:TextStyle(color:Color(0xFFE91E63)),),),],),),);}

简介默认显示3行,点击"展开"可以查看完整内容。

歌曲列表头部

在歌曲列表前添加头部信息。

Widget_buildSongListHeader(){returnSliverToBoxAdapter(child:Padding(padding:constEdgeInsets.symmetric(horizontal:16,vertical:8),child:Row(children:[constText('歌曲列表',style:TextStyle(fontSize:16,fontWeight:FontWeight.bold),),constSizedBox(width:8),Text('共10首',style:TextStyle(color:Colors.grey.withOpacity(0.8),fontSize:14),),],),),);}

显示"歌曲列表"标题和歌曲总数,让用户了解专辑包含多少首歌。

评论入口

可以添加评论入口让用户查看和发表评论。

Widget_buildCommentEntry(){returnSliverToBoxAdapter(child:ListTile(leading:constIcon(Icons.comment_outlined,color:Colors.grey),title:constText('评论'),subtitle:constText('1234条评论',style:TextStyle(color:Colors.grey,fontSize:12)),trailing:constIcon(Icons.chevron_right,color:Colors.grey),onTap:()=>Get.toNamed('/comment',arguments:{'albumId':id}),),);}

显示评论数量,点击跳转到评论页面。

总结

专辑详情页的实现使用了CustomScrollView和多个Sliver组件的组合:SliverAppBar实现可折叠的头部,SliverToBoxAdapter包装普通Widget,SliverList构建歌曲列表。通过合理的布局和交互设计,为用户提供了清晰的专辑信息展示和便捷的操作入口。在实际项目中,还需要对接后端接口获取真实的专辑数据。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/1 23:37:13

Flutter for OpenHarmony音乐播放器App实战24:我喜欢的音乐实现

我喜欢的音乐是用户收藏歌曲的专属歌单&#xff0c;用户可以在这里找到所有标记为喜欢的歌曲。本篇将详细介绍如何实现我喜欢的音乐页面&#xff0c;包括歌单头部设计、排序功能和歌曲操作菜单。 功能分析 我喜欢的音乐页面需要实现以下功能&#xff1a;渐变封面展示、歌曲数…

作者头像 李华
网站建设 2026/4/1 21:23:22

遗传算法的静态二维栅格路径规划附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…

作者头像 李华
网站建设 2026/4/8 19:08:11

计算机Net毕设实战-基于net的实验室管理信息系统的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/10 16:12:32

上海靠谱电子产品开发,实邦电子经验丰富吗?

上海靠谱电子产品开发&#xff0c;实邦电子经验丰富尽显实力公司简介&#xff1a;十六载深耕&#xff0c;铸就电子行业典范上海实邦电子科技有限公司自 2009 年成立以来&#xff0c;至今已稳健发展 16 年。在这 16 年的岁月里&#xff0c;实邦电子凭借着对电子科技领域的执着追…

作者头像 李华