Flutter实战 | 从 0 搭建「网易云音乐」APP(九、搜索页面、底部播放控制栏)
本系列可能会伴随大家很长时间,这里我会从0开始搭建一个「网易云音乐」的APP出来。下面是该APP 功能的思维导图:
前期回顾:
1.Flutter实战 | 从 0 搭建「网易云音乐」APP(一、创建项目、添加插件、通用代码)2.Flutter实战 | 从 0 搭建「网易云音乐」APP(二、Splash Page、登录页、发现页)3.Flutter实战 | 从 0 搭建「网易云音乐」APP(三、每日推荐、推荐歌单)4.Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)5.Flutter实战 | 从 0 搭建「网易云音乐」APP(五、播放功能逻辑)6.Flutter实战 | 从 0 搭建「网易云音乐」APP(六、歌词(一))7.Flutter实战 | 从 0 搭建「网易云音乐」APP(七、歌词(二))8.Flutter实战 | 从 0 搭建「网易云音乐」APP(八、我的页面)
本篇为第九篇,在这里我们会搭建「搜索页面、底部播放控制栏」。
搜索页 | 搜索结果页 |
0. 写在前面
上一周一直没更新代码与文章,是因为公司公费去厦门旅游来着,所以好好放松了一周。这周开始恢复代码与文章的更新,最近收到很多童鞋反馈说比较卡,我建议加我个人微信「17610912320」,来探讨一下是哪个地方,具体在哪里卡。也欢迎 PR,让我们一起为这个项目添砖加瓦!
1. 搜索页
话不多说,接着就来我们的搜索页,先看一下图,然后梳理一下需求:1.历史记录(无历史记录的时候不显示)2.热搜榜
1. 历史记录
先来搞历史记录,历史记录肯定是要存在我们本地的,那就需要用到
shared_preferences了。这方面的就不多说了,看看文档,都懂的。然后是 UI,不知道有没有童鞋记得我以前写过一篇文章:Flutter Wrap & Chip。 在这里完全就能用得上,而且不需要那么多花里胡哨的,只有一个文字就行了。来看一下如何定义:
Wrap( spacing: ScreenUtil().setWidth(20), children: historySearchList .map((v) => GestureDetector( onTap: () { searchText = v; _search(); }, child: Chip( label: Text( v, style: common14TextStyle, ), backgroundColor: Color(0xFFf2f2f2), ), )) .toList(), ),逻辑如下:1.用
Wrap包裹住
chip2.并设置每个
chip的间隔为 203.然后根据
historySearchList的数据来返回
chip4.最后改变一下
chip的背景颜色即可但是,不要忘了我们还有「清空历史记录」的功能,页面如下: 在点击 小垃圾桶的时候弹出,这个也很简单:
IconButton( icon: Icon( Icons.delete_outline, color: Colors.grey, ), onPressed: () { showDialog( context: context, builder: (context) { return AlertDialog( content: Text( "确定清空全部历史记录?", style: common14GrayTextStyle, ), actions: <Widget>[ FlatButton( onPressed: () { Navigator.of(context).pop(); }, child: Text('取消'), textColor: Colors.red, ), FlatButton( onPressed: () { setState(() { historySearchList.clear(); Application.sp.remove("search_history"); }); Navigator.of(context).pop(); }, child: Text('清空'), textColor: Colors.red, ), ], ); }); }, )在点击这个
IconButton的时候调用
showDialog方法,然后根据点击的按钮做相应的操作即可。
2. 热搜榜
热搜榜这个就更简单了,直接就是一个
ListView。刚开始看到这个布局的时候想到的是
ListTile,但是间距什么的不好控制,所以只能自己写了。
Text( curData.searchWord, style: index < 3 ? w500_16TextStyle : common16TextStyle, ),最前面排名字体颜色的控制直接用
index就ok,后面的也没什么好说的,直接撸就完了。
2. 搜索结果页
搜索结果页其实是和「搜索页」在一起的,由搜索状态控制:
_isSearching ? _buildSearchingPage() : _buildUnSearchingPage();搜索结果页分 7 页:1.综合2.单曲3.专辑4.歌手5.歌单6.用户7.视频其中「综合」页面包含了剩下的每一页的UI,所以我们在写「综合」页面的时候每一个控件都封装一下。具体UI上面就不说了,有一个需要注意的地方就是:在综合页面需要跳转别的页面,这里我使用的是在创建「综合」页面的时候传入点击事件,然后在点击的时候调用:
SearchMultipleResultPage(this.keywords, {@required this.onTapMore, @required this.onTapSimText});最后在主页面用
controller来控制就好了。
3. 底部播放控制栏
接到很多人反馈说找不到当前听的是哪首歌????,当时觉得这个东西比较简单,就没有写,昨天花了一点时间给写完了。我为什么说他简单呢。。。不是我装x,是真的简单,听我说!我们在编写播放页面的时候就已经把关于歌曲播放功能的 model:
PlaySongsModel给写好了,所有的功能都在这里,所以我们想要写一个「播放控制栏」真的是分分钟搞定。so,控制栏逻辑如下:1.在播放的时候保存当前歌曲列表和当前 index 到本地2.在重新打开 APP 的时候点击播放可以播放上次播放的歌曲第一个保存,很简单了,使用
shared_preferences:
// 保存当前歌曲到本地 void saveCurSong(){ Application.sp.remove('playing_songs'); Application.sp.setStringList('playing_songs', _songs.map((s) => FluroConvertUtils.object2string(s)).toList()); Application.sp.setInt('playing_index', curIndex); }第二个取出数据:
// 判断是否有保存的歌曲列表 if(Application.sp.containsKey('playing_songs')){ List<String> songs = Application.sp.getStringList('playing_songs'); playSongsModel.addSongs(songs.map((s) => Song.fromJson(FluroConvertUtils.string2map(s))).toList()); int index = Application.sp.getInt('playing_index'); playSongsModel.curIndex = index; }关于UI更新什么的根本不需要考虑,
Provider直接搞定了,什么逻辑都不用写。暂停播放之类的,点击事件如下:
GestureDetector( onTap: (){ if(model.curState == null){ model.play(); }else { model.togglePlay(); } } )当我们重新打开APP的时候,这个时候
curState是 null,这个时候我们调用 恢复/暂停 方法是没有效果的,所以我们要先调用
play()方法。还有一个地方需要注意,在 iPhone 上有些是有「控制条」的,所以我们要加上这个高度:
height: ScreenUtil().setWidth(110) + Application.bottomBarHeight写好以后在需要使用的页面加上就行了。
4. 总结
感觉大部分功能已经完成,但是看了一下思维导图。。。慢慢来吧!大家如果有好的建议的话,欢迎提 issue,我会在第一时间回复。该系列文章代码已传至 GitHub:https://github.com/wanglu1209/NeteaseClouldMusic另我个人创建了一个「Flutter 交流群」,可以添加我个人微信 「17610912320」来入群。
- ios开发中APP底部上滑不能调出如WiFi、蓝牙、播放等的设置页面的解决办法
- 关于Android 悬浮窗问题以及仿网易云音乐底部播放控制栏实现
- ios开发中APP底部上滑不能调出如WiFi、蓝牙、播放等的设置页面的解决的方法
- CSS控制DIV永远固定在页面底部不随滚动而滚动
- iOS学习笔记51-iOS 音乐类App必备功能:后台播放、锁屏封面、远程播放控制
- 在页面中控制媒体流的起播点和播放长度
- Android实战 - 音心播放器 (MusicActivity-音乐播放页面界面实现)
- Vue实现魅族ebook读书app中搜索页面的搜索热词布局
- Swift实战-豆瓣电台(九)简单手势控制暂停播放(全文完)
- 用JavaScript搭建高性能App - React Native实战教程
- Android实战简易教程-第四十八枪(App引导页面效果实现)
- 安卓 实现网易云音乐底部播放栏效果之使用自定义BaseActivity实现 下
- 创建多媒体APP 之 音频播放:控制你的APP里面音频的声音大小和播放
- 在页面中控制媒体流的起播点和播放长度
- Android官方开发文档Training系列课程中文版:管理音频播放之控制APP的音量与播放
- ExtJs4实战(二) 搭建主页面
- iOS UIWebView 全屏播放视频横屏 app其他页面不支持横屏
- 实战使用Axure设计App,使用WebStorm开发(3) – 构建页面架构
- APP开发流程实例讲解-儒释道网络电台八天开发全程-实现功能代码:播放控制
- 安卓 实现网易云音乐底部播放栏效果之使用UI绑定到Service上实现