news 2026/3/7 6:21:39

Flutter for OpenHarmony音乐播放器App实战15:专辑列表实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter for OpenHarmony音乐播放器App实战15:专辑列表实现

专辑列表页面展示新上架的专辑,用户可以浏览并点击进入专辑详情页。本篇我们使用网格布局来实现专辑列表,每个专辑显示封面、名称和歌手。这是音乐App中展示专辑的常见方式。

功能分析

专辑列表页面需要实现以下功能:网格布局展示专辑、专辑封面圆角显示、专辑名称和歌手信息展示、点击专辑进入详情页。这个页面和歌手列表类似,但专辑项的布局稍有不同,需要显示更多信息。

核心技术点

本篇涉及的核心技术包括:GridView.builder网格布局、BoxDecoration圆角装饰、Column垂直布局、GetX路由导航、动态颜色分配。

对应代码文件

lib/pages/album/album_list_page.dart

完整代码实现

import'package:flutter/material.dart';import'package:get/get.dart';import'album_detail_page.dart';classAlbumListPageextendsStatelessWidget{constAlbumListPage({super.key});@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('新碟上架'),),

这段代码导入了Flutter核心库、GetX状态管理库以及专辑详情页面。AlbumListPage继承StatelessWidget,因为页面不需要管理内部状态。Scaffold提供基础页面结构,AppBar显示"新碟上架"标题,表明这是展示最新专辑的页面。

body:GridView.builder(padding:constEdgeInsets.all(16),gridDelegate:constSliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2,childAspectRatio:0.75,crossAxisSpacing:12,mainAxisSpacing:12,),itemCount:20,

GridView.builder用于构建网格布局,padding设置16像素内边距让内容不紧贴屏幕边缘。gridDelegate配置网格为2列,宽高比0.75意味着高度是宽度的1.33倍,这个比例适合显示专辑封面加上两行文字。间距设为12像素,itemCount设为20表示显示20张专辑。

itemBuilder:(context,index)=>GestureDetector(onTap:()=>Get.to(()=>AlbumDetailPage(id:index)),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[// 专辑封面Expanded(child:Container(decoration:BoxDecoration(borderRadius:BorderRadius.circular(12),color:Colors.primaries[index%Colors.primaries.length].withOpacity(0.3),),

itemBuilder构建每个专辑项。GestureDetector处理点击事件,通过Get.to导航到专辑详情页并传递专辑ID。Column垂直排列封面、名称和歌手,crossAxisAlignment设为start让文字左对齐。Expanded让封面区域占据剩余空间,Container使用BoxDecoration实现圆角背景。

child:constCenter(child:Icon(Icons.album,size:60,color:Colors.white70,),),),),constSizedBox(height:8),

封面中央显示专辑图标,size设为60像素比歌单图标更大,突出专辑的视觉效果。颜色使用白色70%透明度,与半透明背景形成对比。SizedBox添加封面和标题之间8像素的间距,让布局更加舒适。

// 专辑名称Text('专辑${index+1}',style:constTextStyle(fontWeight:FontWeight.w500,),maxLines:1,overflow:TextOverflow.ellipsis,),// 歌手名称constText('歌手名称',style:TextStyle(color:Colors.grey,fontSize:12,),),],),),),);}}

专辑名称使用fontWeight.w500加粗显示,让主要信息更突出。maxLines限制一行,overflow设置溢出显示省略号。歌手名称使用灰色12像素小字体作为辅助信息,与专辑名称形成主次分明的视觉层次。整体布局包含封面、专辑名和歌手名三部分。

GridView网格布局详解

GridView.builder是创建网格列表的最佳选择,它采用懒加载方式只构建可见区域的子项,对于长列表来说性能更好。与GridView.count相比,builder模式更适合数据量大或动态数据的场景。

// GridView.builder的基本结构GridView.builder(padding:constEdgeInsets.all(16),gridDelegate:constSliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2,childAspectRatio:0.75,crossAxisSpacing:12,mainAxisSpacing:12,),itemCount:20,itemBuilder:(context,index){// 构建每个子项returnbuildItem(index);},)

padding设置网格的内边距,itemCount指定总数量,itemBuilder构建每个子项。这种模式让代码结构清晰,易于维护和扩展。

SliverGridDelegateWithFixedCrossAxisCount说明

这个委托类定义网格的布局规则,是GridView最常用的布局方式:

// 网格布局参数详解constSliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2,// 每行显示2列childAspectRatio:0.75,// 子项宽高比(宽/高)crossAxisSpacing:12,// 列间距mainAxisSpacing:12,// 行间距)

crossAxisCount设为2表示每行显示2个专辑。childAspectRatio设为0.75,意味着高度是宽度的1.33倍,这个比例适合显示专辑封面加上两行文字。如果需要显示更多文字,可以进一步减小这个值。

BoxDecoration圆角装饰

封面使用Container配合BoxDecoration实现圆角背景:

// 圆角装饰示例Container(decoration:BoxDecoration(borderRadius:BorderRadius.circular(12),color:Colors.primaries[index%Colors.primaries.length].withOpacity(0.3),),child:constCenter(child:Icon(Icons.album,size:60,color:Colors.white70),),)

borderRadius.circular(12)设置12像素圆角,让封面更加圆润美观。实际项目中,这里应该使用DecorationImage显示网络图片,可以配合CachedNetworkImage实现图片缓存。

动态颜色分配

封面使用Colors.primaries数组中的颜色,通过取模运算让每个专辑有不同的颜色:

// 动态颜色分配color:Colors.primaries[index%Colors.primaries.length].withOpacity(0.3)

Colors.primaries是Flutter内置的主色调数组,包含18种颜色。取模运算确保index超出数组长度时能循环使用颜色。withOpacity(0.3)降低透明度让颜色更柔和,增加视觉多样性的同时不会过于刺眼。

文本样式设计

专辑项包含两行文字,使用不同的样式区分主次信息:

// 主标题样式Text('专辑名称',style:constTextStyle(fontWeight:FontWeight.w500),maxLines:1,overflow:TextOverflow.ellipsis,)// 副标题样式constText('歌手名称',style:TextStyle(color:Colors.grey,fontSize:12),)

专辑名称使用fontWeight.w500加粗,歌手名称使用灰色小字体。这种设计让主要信息(专辑名)更突出,辅助信息(歌手名)作为补充。maxLines和overflow处理文本溢出,保证界面整洁。

页面导航实现

点击专辑时使用GetX进行页面导航:

// 页面导航GestureDetector(onTap:()=>Get.to(()=>AlbumDetailPage(id:index)),child:// 专辑项内容)

Get.to是GetX提供的导航方法,通过构造函数传递专辑ID。详情页可以根据ID加载对应的专辑数据,包括专辑信息、歌曲列表等。这种方式让页面之间的数据传递变得简单直观。

布局结构说明

每个专辑项使用Column垂直排列三个部分:

// 专辑项布局结构Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Expanded(child:/* 封面 */),constSizedBox(height:8),Text(/* 专辑名 */),Text(/* 歌手名 */),],)

crossAxisAlignment.start让文字左对齐,Expanded让封面占据剩余空间。SizedBox添加间距,让各元素之间保持适当距离。这种布局结构清晰,易于理解和修改。

小结

本篇实现了音乐播放器的专辑列表页面。使用GridView.builder实现网格布局,每行显示2个专辑。每个专辑项包含封面、名称和歌手三部分,使用Column垂直排列。通过调整childAspectRatio参数可以控制子项的宽高比,适配不同的设计需求。这种网格布局在音乐App中非常常见,掌握这些技术可以轻松实现各种列表展示效果。


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

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

程序员的价值与社会贡献

程序员的价值与社会贡献 关键词:程序员、价值、社会贡献、技术创新、数字化转型 摘要:本文深入探讨了程序员的价值与社会贡献。首先介绍了文章的背景信息,包括目的、预期读者、文档结构和相关术语。接着阐述了程序员工作的核心概念,分析了其工作原理和架构,并通过Mermaid流…

作者头像 李华
网站建设 2026/3/7 3:33:19

从入门到年薪百万:AI大模型学习路线与技能图谱(必收藏)

AI行业冰火两重天:算法工程师年薪百万,传统程序员面临替代。行业呈金字塔结构,塔尖是核心算法,塔身是应用开发,塔底是数据标注。无论选择哪条路,都需要投入1000小时打磨基本功。数学基础、编程思维和算法设…

作者头像 李华
网站建设 2026/3/5 21:17:25

大模型工具使用技术演进:从Prompt到A2A通信协议全解析

本文介绍了大模型使用工具的三种技术演进:1)Prompt工程初级阶段,通过system prompt定义工具列表,但依赖模型理解能力;2)Function calling通过模型微调提高准确性但缺乏跨模型一致性;3&#xff0…

作者头像 李华
网站建设 2026/3/5 10:18:24

AgentScope 深度解读:多智能体开发框架的工程化实践

AgentScope 深度解读:多智能体开发框架的工程化实践 一句话总结:AgentScope 把多智能体开发从"每次都要造轮子"变成"拼积木"——消息驱动的通信、内置的容错机制、本地和分布式代码零差异,这三板斧砍下来,工业…

作者头像 李华
网站建设 2026/3/5 7:23:28

AI应用架构师的神操作:企业级LLM定制化方案深度剖析

AI应用架构师的神操作:企业级LLM定制化方案深度剖析 引言:为什么企业需要“定制化LLM”? 痛点引入:通用LLM的“水土不服” 当ChatGPT火遍全球时,很多企业第一时间尝试用它解决业务问题—— 某银行用GPT-4处理贷款申请审…

作者头像 李华
网站建设 2026/3/6 4:08:23

千万别学网络安全?给新手/转行者的3个“真心劝退”理由

前言 很多人说千万别学网络安全专业的原因是因为网络安全专业学习的课程非常难。就业要求高。很多同学在大学开始接触网络空间安全专业时,才发现:对于自己来说,网络空间安全专业相关的课程学习难度有点高。 为什么说千万别学网络安全专业的原…

作者头像 李华