Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)

本系列可能会伴随大家很长时间,这里我会从0开始搭建一个「网易云音乐」的APP出来。

下面是该APP 功能的思维导图:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第1张图片

前期回顾:

1.2.3.

本篇为第四篇,在这里我们会搭建排行榜页面、播放歌曲页面。

排行榜页面

先来看图:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第2张图片

页面很简单,两个列表:

1.官方榜 -> ListView2.更多榜单 -> GridView

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第3张图片

注意:这里一定要使用这个接口,才会出现每个榜单中的1. 2. 3. 首歌。

话不多说,直接来看接口返回值:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第4张图片

返回值大致如此(删除了一部分用不到的数据)。

可以看到我标了两个红框框,这就是该接口 list 参数中不一样的地方:一个有歌,一个没有歌。

这代表了什么?这就是官方榜单和更多榜单的区别!

既然如此,区分的代码就如下了:

var officialTopListData =	
  data.list.where((l) => l.tracks.isNotEmpty).toList(); // 官方榜的数据	
var moreTopListData =	
  data.list.where((l) => l.tracks.isEmpty).toList(); // 更多榜单的数据

只需要判断 tracks 的数据是否为空就好了。

然后就只需要根据各自的数据来创建列表就好了。

不过我这里「官方榜」也是列表的一部分。所以在点击 index 的时候,不要忘记 -1。

接下来就是跳转到「榜单详情页」。

因为开始在查看接口文档的过程中,找到了这样一段:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第5张图片

当时就想着在「榜单接口」中找到该id,但是我发现根本没有!

然而就当我绝望的时候在 GitHub 的 issue 中找到这么一段对话:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第6张图片

啊!!瞬间幸福感爆棚!页面我都不用写了,直接用原来的「歌单」页面就好了!

so easy!

播放歌曲页面

「播放歌曲页面」可以说是整个APP的灵魂所在。

逻辑什么的之后再说,这节就单单来说UI。

如图所示:

播放 暂停
Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第7张图片 Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第8张图片

从上到下,七个部分:

1.标题(主标题、副标题)2.唱针3.碟片4.对该歌曲的操作(喜欢、下载等)5.进度条6.对播放的操作(暂停、下一首等)7.最后还有一个背景

1. 标题

首先,这里的标题是两行的。

AppBar 的title 需要的是一个 Widget,那我们就可以随意操作:

title: Column(	
  mainAxisSize: MainAxisSize.min,	
  children: [	
    Text(	
      model.curSong.name,	
      style: commonWhiteTextStyle,	
    ),	
    Text(	
      model.curSong.artists,	
      style: smallWhite70TextStyle,	
    ),	
  ],	
)

2. 唱针

装在唱机唱头上的针,一般由钢或人造宝石制成。它跟随声盘纹道的调制,把所得机械运动传送给唱头的换能元件,使之转换为相应的声频信号。

这里的唱针是一个图片,他的作用就是移开,放上,也就是对应着 播放、暂停。

这里有个问题是,唱针是个图片,我们要对该图片进行旋转操作,

而旋转的中心点左上角图中1的位置:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第9张图片

那我们就要对整个图片做一个了解,首先看看这个中心在原图的哪里:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第10张图片

用自带的看图工具大致看一下,在 45 * 45 的位置,然后查看一下原图的尺寸:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第11张图片

有了这两个参数我们就好定义中心点:

RotationTransition(	
  turns: _stylusAnimation,	
  alignment: Alignment(	
    -1 +	
    (ScreenUtil().setWidth(45 * 2) /	
     (ScreenUtil().setWidth(293))),	
    -1 +	
    (ScreenUtil().setWidth(45 * 2) /	
     (ScreenUtil().setWidth(504)))),	
  child: Image.asset(	
    'images/bgm.png',	
    width: ScreenUtil().setWidth(146.5),	
    height: ScreenUtil().setWidth(252),	
  ),	
),

首先我们设置该图片的宽高比和原图一致。

然后定义 Alignment,注意:

Alignment 左上角的值为:Alignment(-1.0, -1.0)

中心点的的值为:Alignment(0.0, 0.0)

右下角的值为:Alignment(1.0, 1.0)

从上面我们可以看得出来,Alignment 是从中心开始的坐标系,左和上为负数、右和下为正数。

那我们控制唱针的中心是在左上角,所以肯定是负数,所以我们用 -1+。

而既然是从中心开始的,那么计算的时候要用刚才看到的坐标 * 2 / 宽(高)。

这样得到的值才是准确的。

3. 碟片

我们所看到的碟片有两种状态:

1.正在转2.停止

也是正好对应上 播放和暂停。

旋转的就不多说了,RotationTransition 了解一下。

监听一下状态,在完成的时候继续就可以了。

4. 对该歌曲的操作(喜欢、下载等)

这个就比较简单了,一个Row 里面全是 Expanded 就可以了。

大致代码如下:

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第12张图片

5. 进度条

进度条也很简单,但是逻辑稍微复杂一点,我们后续再说。

进度条使用 Slider 就可以了。

关于 Slider 的样式,代码如下:

SliderTheme(	
  data: SliderThemeData(	
    trackHeight: ScreenUtil().setWidth(2),	
    thumbShape: RoundSliderThumbShape(	
      enabledThumbRadius: ScreenUtil().setWidth(10),	
    ),	
  ),	
  child: Slider(	
    value: double.parse(curTime),	
    onChanged: (data) {},	
    onChangeStart: (data){	
      model.pausePlay();	
    },	
    onChangeEnd: (data){	
      model.seekPlay(data.toInt());	
    },	
    activeColor: Colors.white,	
    inactiveColor: Colors.white30,	
    min: 0,	
    max: double.parse(totalTime),	
  ),	
),

在 Slider 上面套上 SliderTheme 就可以了。

6. 对播放的操作(暂停、下一首等)

这个也没什么好说的了,和上面对歌曲的操作一样。封装上一个组件,然后调用就好了。

7. 背景

背景还是使用的 BackdropFilter,参数 sigma 设置成100。

这里模拟器和真机是有区别的,在模拟器上最多设置成20,再大就花了。

所以我建议跑播放歌曲的时候,最好用真机,不然会卡的要命。。

总结

这一章节我们搭建了排行榜页面、播放歌曲页面。

其中「播放歌曲」页面是该APP的一个难点和重点。

我这里的逻辑也还没有写完,后续会慢慢捋出来发文的。

该系列文章代码已传至 GitHub:https://github.com/wanglu1209/NeteaseClouldMusic

另我个人创建了一个「Flutter 交流群」,可以添加我个人微信 「17610912320」来入群。

Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面)_第13张图片

你可能感兴趣的:(Flutter实战 | 从 0 搭建「网易云音乐」APP(四、排行榜、播放页面))