Flutter for OpenHarmony音乐播放器App实战:我的音乐库实现
摘要 本文实现了一个音乐库管理页面,包含三大核心模块:音乐统计卡片展示本地歌曲、收藏歌曲和歌单数量;快捷入口列表提供本地音乐、下载管理、最近播放和收藏功能;歌单列表展示用户创建的歌单。页面采用模块化设计,使用渐变卡片增强视觉效果,通过数据驱动方式构建UI元素。关键技术包括GetX路由导航、ListView构建列表和响应式布局,为用户提供集中管理个人音乐资产的一站式入口。

我的音乐库是用户管理个人音乐的中心,包含本地音乐、下载管理、最近播放、收藏歌曲等功能入口,以及用户创建的歌单列表。这个页面是用户个人音乐资产的集中展示,需要清晰地组织各种功能入口。本篇我们来实现这个功能丰富的音乐库页面。
功能分析
我的音乐库页面需要实现以下功能:音乐统计卡片(本地歌曲数、收藏数、歌单数)、快捷入口列表(本地音乐、下载管理、最近播放、我的收藏)、创建的歌单列表、创建新歌单入口。这个页面是用户管理个人音乐的核心入口,设计上需要层次分明、操作便捷。
核心技术点
本篇涉及的核心技术包括:渐变卡片展示统计数据、ListTile构建快捷入口列表、ListView.builder展示歌单列表、数据驱动的UI构建方式、GetX路由导航。
对应代码文件
lib/pages/music/my_music_page.dart
完整代码实现
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../local/local_music_page.dart';
import '../download/download_page.dart';
import '../recent/recent_play_page.dart';
import '../favorite/favorite_page.dart';
import '../playlist/create_playlist_page.dart';
这段代码导入了Flutter核心库、GetX状态管理库以及各个功能页面。我的音乐库需要跳转到本地音乐、下载管理、最近播放、收藏和创建歌单等页面,因此需要导入这些页面的引用。GetX提供了简洁的路由导航API。
class MyMusicPage extends StatelessWidget {
const MyMusicPage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('我的音乐')
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
_buildMusicStats(),
const SizedBox(height: 24),
MyMusicPage继承StatelessWidget,因为页面不需要管理内部状态。Scaffold提供基础页面结构,AppBar显示"我的音乐"标题。SingleChildScrollView包裹Column实现整体滚动,padding设置16像素的内边距让内容与边缘保持距离。
_buildQuickAccess(),
const SizedBox(height: 24),
_buildMyPlaylists(),
const SizedBox(height: 100),
],
),
),
);
}
页面主体包含三个模块:音乐统计卡片、快捷入口列表和我的歌单。每个模块之间使用SizedBox添加24像素间距,底部留100像素空间避免被迷你播放器遮挡。这种模块化的布局方式让代码结构清晰,便于维护和扩展。
Widget _buildMusicStats() {
return Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [
Color(0xFFE91E63),
Color(0xFF9C27B0)
]
),
borderRadius: BorderRadius.circular(16)
),
_buildMusicStats方法构建音乐统计卡片。Container使用渐变背景,从粉色(E91E63)过渡到紫色(9C27B0),配合16像素圆角。这种渐变设计让卡片更有视觉吸引力,同时与App的主题色保持一致。
child: const Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Text(
'128',
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold
)
),
Text(
'本地歌曲',
style: TextStyle(color: Colors.white70)
)
]
),
Row水平排列三组统计数据,spaceAround让它们均匀分布在卡片中。每组统计数据使用Column垂直排列数字和标签。数字使用24像素白色粗体字突出显示,标签使用白色70%透明度作为辅助信息,形成主次分明的视觉层次。
Column(
children: [
Text(
'56',
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold
)
),
Text(
'收藏歌曲',
style: TextStyle(color: Colors.white70)
)
]
),
Column(
children: [
Text(
'12',
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold
)
),
Text(
'创建歌单',
style: TextStyle(color: Colors.white70)
)
]
),
],
),
);
}
三组数据分别展示本地歌曲、收藏歌曲和创建歌单的数量,让用户快速了解自己的音乐资产概况。统一的样式设计保证了视觉一致性,渐变背景让整个卡片成为页面的视觉焦点。
Widget _buildQuickAccess() {
final items = [
{
'icon': Icons.folder,
'label': '本地音乐',
'count': '128',
'page': () => const LocalMusicPage()
},
{
'icon': Icons.download,
'label': '下载管理',
'count': '45',
'page': () => const DownloadPage()
},
{
'icon': Icons.history,
'label': '最近播放',
'count': '200',
'page': () => const RecentPlayPage()
},
{
'icon': Icons.favorite,
'label': '我的收藏',
'count': '56',
'page': () => const FavoritePage()
},
];
_buildQuickAccess方法构建快捷入口列表。items列表存储每个入口的数据,包括图标、文字标签、数量和对应的页面构造函数。使用Map结构存储数据,方便后续遍历和访问。这种数据驱动的方式让代码更易维护,添加或修改入口只需修改数据即可。
return Column(
children: items.map((item) => ListTile(
leading: Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: const Color(0xFFE91E63).withOpacity(0.1),
borderRadius: BorderRadius.circular(12)
),
child: Icon(
item['icon'] as IconData,
color: const Color(0xFFE91E63)
)
),
使用map方法遍历items生成ListTile列表。leading放置图标容器,使用粉色10%透明度背景和12像素圆角。图标使用粉色主题色,与整体设计风格保持一致。Container的固定尺寸确保所有图标容器大小一致。
title: Text(item['label'] as String),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
item['count'] as String,
style: const TextStyle(color: Colors.grey)
),
const Icon(
Icons.chevron_right,
color: Colors.grey
)
]
),
onTap: () => Get.to(item['page'] as Widget Function()),
)).toList(),
);
}
title显示入口名称,trailing显示数量和箭头图标。mainAxisSize设为min让Row只占必要宽度,避免撑满整行。onTap通过Get.to导航到对应页面,实现页面跳转功能。toList()将map结果转换为List供Column使用。
Widget _buildMyPlaylists() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'创建的歌单',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold
)
),
IconButton(
icon: const Icon(
Icons.add_circle_outline,
color: Color(0xFFE91E63)
),
onPressed: () => Get.to(
() => const CreatePlaylistPage()
)
),
],
),
_buildMyPlaylists方法构建歌单列表模块。标题行左侧显示"创建的歌单",右侧放置添加按钮,点击跳转到创建歌单页面。添加按钮使用粉色主题色,突出显示可操作性。spaceBetween让标题和按钮分别靠左和靠右。
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 5,
itemBuilder: (context, index) => ListTile(
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.primaries[index % Colors.primaries.length]
.withOpacity(0.3)
),
child: const Icon(
Icons.queue_music,
color: Colors.white70
)
),
ListView.builder构建歌单列表,shrinkWrap设为true让列表高度自适应内容,NeverScrollableScrollPhysics禁用内部滚动避免与外层滚动冲突。leading放置歌单封面,使用不同颜色的半透明背景区分不同歌单,增加视觉多样性。
title: Text('我的歌单 ${index + 1}'),
subtitle: Text('${(index + 1) * 10} 首'),
trailing: const Icon(Icons.more_vert),
),
),
],
);
}
}
title显示歌单名称,subtitle显示歌曲数量,trailing放置更多操作按钮。每个歌单项包含封面、名称、数量和操作按钮,信息展示完整且布局紧凑。点击更多按钮可以弹出操作菜单。
渐变卡片设计详解
渐变卡片使用LinearGradient实现颜色过渡效果,从粉色(E91E63)过渡到紫色(9C27B0)。这种设计让统计卡片更有视觉吸引力,同时与App的主题色保持一致。配合圆角和内边距,整体效果更加精致。渐变方向默认从左到右,也可以通过begin和end参数自定义。
数据驱动的列表构建
快捷入口列表使用数据驱动的方式构建,将图标、文字、数量和页面信息存储在Map中,通过map方法遍历生成ListTile。这种方式让代码更易维护,添加或修改入口只需修改数据即可,无需改动UI代码。这是Flutter开发中常用的模式。
ListView嵌套滚动处理
在SingleChildScrollView中嵌套ListView时,需要设置shrinkWrap为true让ListView高度自适应,同时设置NeverScrollableScrollPhysics禁用内部滚动,避免滚动冲突。这是Flutter中常见的嵌套滚动处理方式,确保用户体验流畅。
GetX路由导航说明
GetX提供了简洁的路由导航API,Get.to()方法接收页面构造函数作为参数,自动处理页面跳转动画和返回逻辑。相比Navigator.push,代码更加简洁,且不需要context参数,可以在任何地方调用。
小结
本篇实现了音乐播放器的我的音乐库页面。通过渐变卡片展示音乐统计数据,使用ListTile构建快捷入口列表,用ListView展示用户创建的歌单。数据驱动的方式让代码更易维护,统一的样式设计保证了视觉一致性。音乐库页面为用户提供了管理个人音乐的完整功能入口,是音乐App的重要组成部分。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)