Flutter實戰 | 從 0 搭建「網易雲音樂」APP(4、排行榜、播放頁面)

本系列可能會伴隨你們很長時間,這裏我會從0開始搭建一個「網易雲音樂」的APP出來。git

下面是該APP 功能的思惟導圖:github

前期回顧:微信

  1. Flutter實戰 | 從 0 搭建「網易雲音樂」APP(1、建立項目、添加插件、通用代碼)
  2. Flutter實戰 | 從 0 搭建「網易雲音樂」APP(2、Splash Page、登陸頁、發現頁)
  3. Flutter實戰 | 從 0 搭建「網易雲音樂」APP(3、每日推薦、推薦歌單)

本篇爲第四篇,在這裏咱們會搭建排行榜頁面、播放歌曲頁面。ide

排行榜頁面

先來看圖:工具

頁面很簡單,兩個列表:ui

  1. 官方榜 -> ListView
  2. 更多榜單 -> GridView

注意:這裏必定要使用這個接口,纔會出現每一個榜單中的1. 2. 3. 首歌。spa

話很少說,直接來看接口返回值:插件

返回值大體如此(刪除了一部分用不到的數據)。3d

能夠看到我標了兩個紅框框,這就是該接口 list 參數中不同的地方:一個有歌,一個沒有歌。code

這表明了什麼?這就是官方榜單和更多榜單的區別!

既然如此,區分的代碼就以下了:

var officialTopListData =
  data.list.where((l) => l.tracks.isNotEmpty).toList(); // 官方榜的數據
var moreTopListData =
  data.list.where((l) => l.tracks.isEmpty).toList(); // 更多榜單的數據
複製代碼

只須要判斷 tracks 的數據是否爲空就行了。

而後就只須要根據各自的數據來建立列表就行了。

不過我這裏「官方榜」也是列表的一部分。因此在點擊 index 的時候,不要忘記 -1。

接下來就是跳轉到「榜單詳情頁」。

由於開始在查看接口文檔的過程當中,找到了這樣一段:

當時就想着在「榜單接口」中找到該id,可是我發現根本沒有!

然而就當我絕望的時候在 GitHub 的 issue 中找到這麼一段對話:

啊!!瞬間幸福感爆棚!頁面我都不用寫了,直接用原來的「歌單」頁面就行了!

so easy!

播放歌曲頁面

「播放歌曲頁面」能夠說是整個APP的靈魂所在。

邏輯什麼的以後再說,這節就單單來講UI。

如圖所示:

播放 暫停

從上到下,七個部分:

  1. 標題(主標題、副標題)
  2. 唱針
  3. 碟片
  4. 對該歌曲的操做(喜歡、下載等)
  5. 進度條
  6. 對播放的操做(暫停、下一首等)
  7. 最後還有一個背景

1. 標題

首先,這裏的標題是兩行的。

AppBar 的title 須要的是一個 Widget,那咱們就能夠隨意操做:

title: Column(
  mainAxisSize: MainAxisSize.min,
  children: <Widget>[
    Text(
      model.curSong.name,
      style: commonWhiteTextStyle,
    ),
    Text(
      model.curSong.artists,
      style: smallWhite70TextStyle,
    ),
  ],
)
複製代碼

2. 唱針

裝在唱機唱頭上的針,通常由鋼或人造寶石製成。它跟隨聲盤紋道的調製,把所得機械運動傳送給唱頭的換能元件,使之轉換爲相應的聲頻信號。

這裏的唱針是一個圖片,他的做用就是移開,放上,也就是對應着 播放、暫停。

這裏有個問題是,唱針是個圖片,咱們要對該圖片進行旋轉操做,

而旋轉的中心點左上角圖中1的位置:

那咱們就要對整個圖片作一個瞭解,首先看看這個中心在原圖的哪裏:

用自帶的看圖工具大體看一下,在 45 * 45 的位置,而後查看一下原圖的尺寸:

有了這兩個參數咱們就好定義中心點:

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 就能夠了。

大體代碼以下:

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:github.com/wanglu1209/…

另我我的建立了一個「Flutter 交流羣」,能夠添加我我的微信 「17610912320」來入羣。

相關文章
相關標籤/搜索