news 2026/6/9 23:12:45

Flutter for OpenHarmony 音乐播放器App实战25 - 歌词显示实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter for OpenHarmony 音乐播放器App实战25 - 歌词显示实现

前言

歌词显示是音乐播放器中非常受欢迎的功能,用户可以边听歌边看歌词,跟着一起唱。本篇我们来实现一个完整的歌词显示页面,包含歌词滚动列表、当前行高亮、点击跳转、以及底部播放控制。整个页面采用渐变背景设计,营造沉浸式的听歌体验。

功能分析

歌词页面需要实现以下功能:顶部显示歌曲名和歌手名,中间是可滚动的歌词列表,当前播放的歌词行高亮显示,用户可以点击任意歌词行跳转播放,底部提供进度条和播放控制按钮。

页面框架搭建

歌词页面需要管理当前播放行和滚动控制器,使用StatefulWidget实现:

classLyricsPageextendsStatefulWidget{constLyricsPage({super.key});@overrideState<LyricsPage>createState()=>_LyricsPageState();}class_LyricsPageStateextendsState<LyricsPage>{int currentLine=5;finalScrollController_scrollController=ScrollController();

currentLine记录当前播放到第几行歌词,默认值为5表示从第6行开始(索引从0开始)。_scrollController用于控制歌词列表的滚动位置,实现歌词自动滚动到当前行。

歌词数据结构

歌词数据使用List<Map>存储,每条歌词包含时间戳和文本内容:

finalList<Map<String,dynamic>>lyrics=[{'time':0,'text':'作词: 音乐人'},{'time':1,'text':'作曲: 音乐人'},{'time':5,'text':''},{'time':10,'text':'夜空中最亮的星'},{'time':15,'text':'能否听清'},{'time':20,'text':'那仰望的人'},{'time':25,'text':'心底的孤独和叹息'},{'time':30,'text':''},{'time':35,'text':'夜空中最亮的星'},{'time':40,'text':'能否记起'},{'time':45,'text':'曾与我同行'},{'time':50,'text':'消失在风里的身影'},{'time':55,'text':''},{'time':60,'text':'我祈祷拥有一颗透明的心灵'},{'time':65,'text':'和会流泪的眼睛'},{'time':70,'text':'给我再去相信的勇气'},{'time':75,'text':'越过谎言去拥抱你'},];

time字段表示这行歌词对应的播放时间(秒),text字段是歌词内容。空字符串表示歌词间的空行,用于视觉上的分隔。实际项目中这些数据通常从LRC文件解析而来。

页面主体结构

页面使用Stack叠加渐变背景和内容区域:

@overrideWidgetbuild(BuildContextcontext){returnScaffold(backgroundColor:Colors.black,body:Stack(children:[Container(decoration:BoxDecoration(gradient:LinearGradient(begin:Alignment.topCenter,end:Alignment.bottomCenter,colors:[constColor(0xFFE91E63).withOpacity(0.3),Colors.black]))),SafeArea(child:Column(children:[_buildHeader(),Expanded(child:_buildLyrics()),_buildControls(),],),),],),);}

Stack的第一层是渐变背景,从顶部的粉色渐变到底部的黑色。第二层是实际内容,使用Column布局分为三部分:顶部标题栏、中间歌词列表、底部播放控制。SafeArea确保内容不会被状态栏遮挡。

顶部标题栏

标题栏显示歌曲名、歌手名,以及返回和分享按钮:

Widget_buildHeader(){returnPadding(padding:constEdgeInsets.all(16),child:Row(children:[IconButton(icon:constIcon(Icons.keyboard_arrow_down,size:30),onPressed:()=>Get.back()),constExpanded(child:Column(children:[Text('夜空中最亮的星',style:TextStyle(fontSize:18,fontWeight:FontWeight.bold)),SizedBox(height:4),Text('逃跑计划',style:TextStyle(color:Colors.grey)),],),),IconButton(icon:constIcon(Icons.share),onPressed:(){}),],),);}

左侧是向下箭头按钮,点击返回上一页。中间使用Expanded占据剩余空间,显示歌曲名和歌手名,歌曲名使用粗体突出显示。右侧是分享按钮。这种布局是音乐App中常见的设计模式。

歌词列表实现

歌词列表是页面的核心部分,使用ListView.builder构建:

Widget_buildLyrics(){returnListView.builder(controller:_scrollController,padding:constEdgeInsets.symmetric(vertical:100),itemCount:lyrics.length,itemBuilder:(context,index){finalisCurrentLine=index==currentLine;returnGestureDetector(onTap:()=>setState(()=>currentLine=index),child:Container(padding:constEdgeInsets.symmetric(vertical:16,horizontal:32),child:Text(lyrics[index]['text'],textAlign:TextAlign.center,style:TextStyle(fontSize:isCurrentLine?20:16,fontWeight:isCurrentLine?FontWeight.bold:FontWeight.normal,color:isCurrentLine?constColor(0xFFE91E63):Colors.white.withOpacity(0.5),),),),);},);}

padding: const EdgeInsets.symmetric(vertical: 100)在列表顶部和底部添加100像素的空白,让歌词可以滚动到屏幕中央位置。

每行歌词用GestureDetector包裹,点击后更新currentLine实现跳转功能。当前行使用更大的字号(20px vs 16px)、粗体和粉色高亮显示,其他行使用半透明白色,形成明显的视觉对比。

底部播放控制

底部控制区包含进度条和播放按钮:

Widget_buildControls(){returnContainer(padding:constEdgeInsets.all(20),child:Column(children:[Row(children:[constText('2:35',style:TextStyle(color:Colors.grey,fontSize:12)),Expanded(child:Slider(value:0.4,activeColor:constColor(0xFFE91E63),inactiveColor:Colors.grey.withOpacity(0.3),onChanged:(v){})),constText('4:28',style:TextStyle(color:Colors.grey,fontSize:12)),],),

进度条使用Slider组件,左右两侧分别显示当前播放时间和总时长。activeColor设置已播放部分的颜色为粉色,inactiveColor设置未播放部分为灰色。

Row(mainAxisAlignment:MainAxisAlignment.spaceEvenly,children:[IconButton(icon:constIcon(Icons.shuffle),onPressed:(){}),IconButton(icon:constIcon(Icons.skip_previous,size:36),onPressed:(){}),Container(width:64,height:64,decoration:constBoxDecoration(color:Color(0xFFE91E63),shape:BoxShape.circle),child:IconButton(icon:constIcon(Icons.pause,size:32,color:Colors.white),onPressed:(){}),),IconButton(icon:constIcon(Icons.skip_next,size:36),onPressed:(){}),IconButton(icon:constIcon(Icons.repeat),onPressed:(){}),],),],),);}

播放控制按钮使用Row水平排列,spaceEvenly让按钮均匀分布。中间的播放/暂停按钮使用粉色圆形背景突出显示,是整个控制区的视觉焦点。上一首和下一首按钮使用较大的图标(36px),随机播放和循环播放按钮使用默认大小。

页面入口

歌词页面的入口在播放器页面,用户点击"点击查看歌词"文字即可进入:

GestureDetector(onTap:()=>Get.to(()=>constLyricsPage()),child:constText('点击查看歌词',style:TextStyle(color:Colors.white54))),

也可以在播放器页面的进度条区域添加这个入口,让用户更容易发现歌词功能。

扩展思路

实际项目中,歌词同步需要与播放器的播放进度联动。可以监听播放器的进度变化,根据当前播放时间找到对应的歌词行,然后更新currentLine并调用_scrollController.animateTo()平滑滚动到该行。

点击歌词跳转功能需要调用播放器的seek方法,将播放位置跳转到对应歌词的时间点。

还可以添加歌词翻译功能,在原歌词下方显示翻译文本,或者添加歌词字体大小调节、歌词背景模糊等个性化设置。

小结

本篇我们实现了一个功能完整的歌词显示页面,包含渐变背景、歌词列表、当前行高亮、点击跳转和播放控制。通过ListView.builder构建歌词列表,使用条件样式实现当前行高亮效果。渐变背景和统一的粉色主题色让页面视觉效果更加协调。在实际项目中,还需要与播放器进度联动,实现真正的歌词同步滚动功能。


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

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

AI提示设计中,如何让用户“有成就感”?提示工程架构师的4个技巧

AI提示设计中&#xff0c;如何让用户“有成就感”&#xff1f;提示工程架构师的4个核心技巧 引言&#xff1a;为什么“成就感”是AI交互的隐形生命线&#xff1f; 你有没有过这样的经历&#xff1f; 打开某款AI写作工具&#xff0c;输入“帮我写一篇关于职场新人的朋友圈文案…

作者头像 李华
网站建设 2026/6/6 21:38:04

基于金枪鱼群优化算法Kapur最大熵的多阈值分割附Matlab代码

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

作者头像 李华
网站建设 2026/6/9 1:52:48

光伏发电系统(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

光伏发电系统(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码mppt-滞环比较法另有: 1)恒压法、扰动观察法、电导增量法;2)模糊控制法、滞环比较法;3)常见智能算法:粒子群算法、布谷鸟算法、灰狼算法、jaya算法、麻雀算法;4)比较…

作者头像 李华
网站建设 2026/6/6 22:37:59

基于T型三电平并网逆变器的低电压穿越(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

低电压穿越(跟网型-LVRT)基于T型三电平并网逆变器的低电压穿越(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码保证系统电压跌落后&#xff0c;电流仍能保证正常输出&#xff0c;同时提供无功支撑&#xff0c;采用改进电流环算…

作者头像 李华
网站建设 2026/6/6 22:23:17

建议这几个行业的跨境人,碰一碰日本市场

在日本&#xff0c;每5个人中就有一位超过75岁。这不仅是人口结构数据&#xff0c;更是一个正在重塑消费市场的、真实可控且利润稳定的蓝海。 这里的消费者忠诚度高、客单价高、复购力强&#xff0c;一旦建立起信任&#xff0c;便是竞争对手难以撬动的慢生意。 如果你身处以下行…

作者头像 李华