Flutter實戰 | 從 0 搭建「網易雲音樂」APP(一、建立專案、新增外掛、通用程式碼)

Flutter筆記發表於2019-10-09

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

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

Flutter實戰 | 從 0 搭建「網易雲音樂」APP(一、建立專案、新增外掛、通用程式碼)

因為工作的原因,一星期有可能只更新一篇該系列的文章,不過一星期最少一篇。

本章節為第一節,從建立專案說起。

建立「網易雲音樂」專案

首先看一下本地 Flutter 環境:

Flutter實戰 | 從 0 搭建「網易雲音樂」APP(一、建立專案、新增外掛、通用程式碼)

建立命令就都知道了,不用命令的話,用 AS 或者 VS 更簡單。

Flutter實戰 | 從 0 搭建「網易雲音樂」APP(一、建立專案、新增外掛、通用程式碼)

專案建立好後,刪除無用程式碼,然後開始建立資料夾:

Flutter實戰 | 從 0 搭建「網易雲音樂」APP(一、建立專案、新增外掛、通用程式碼)

一共分為六個資料夾:

  • model:存放所有資料類
  • pages:存放所有的頁面
  • provider:存放所有的 Provider
  • route:存放路由相關
  • utils:存放所有的工具類
  • widgets:存放所有封裝好的元件

下面我們開始新增依賴。

新增外掛

首先對我們一些大概的功能有一個瞭解,

例如 網路請求肯定有,那我會選擇 Dio 來當做網路請求的外掛,

下面是目前所想到的外掛:

外掛 作用
Provider 狀態管理,UI、資料 分離
shared_preferences 本地儲存資料,持久化
dio 網路請求
flutter_screenutil 螢幕適配
fluro 路由管理
common_utils Dart 常用工具類
dio_cookie_manager dio cookie 工具
cookie_jar Cookie 管理
permission_handler 許可權處理
path_provider 沙盒路徑
extended_image 屌炸天的 Image 擴充套件

通用程式碼

Flutter實戰 | 從 0 搭建「網易雲音樂」APP(一、建立專案、新增外掛、通用程式碼)

功能如下:

外掛 作用
routes.dart fluro 的路由管理
net_utils.dart 網路請求管理
common_text_style.dart 一些通用的 text 樣式
h_empty_view.dart 橫向空元件(用於佔位)
v_empty_view.dart 縱向空元件(用於佔位)
loading.dart 載入元件
widget_future_builder.dart 網路請求元件
widget_net_error.dart 網路請求失敗元件

其中 widget_future_builder.dart 在我上一篇文章:Flutter | 定義一個通用的多功能網路請求 Widget 中已經說過了,這裡就不多說了。

挑幾個沒說過的說一下。

loading.dart

用於顯示載入中的元件。

開始的時候考慮用 showDialog 來做,但是它預設會把背景變成半透明的黑色。

然後檢視原始碼,發現他是呼叫 showGeneralDialog 來建立的對話方塊,傳入了一個 barrierColor: Colors.black54 來控制的半透明背景。

那我可以自己來使用 showGeneralDialog,關於該控制元件的介紹及使用,我這裡就不多贅述了,可以檢視caijinglong的部落格 - Flutter dialog (2) - showGeneralDialog的使用。

最後我這裡的程式碼就是這樣(擷取一部分):

class Loading {
  static bool isLoading = false;

  static void showLoading(BuildContext context) {
    if (!isLoading) {
      isLoading = true;
      showGeneralDialog(
          context: context,
          pageBuilder: (BuildContext context, Animation animation,
              Animation secondaryAnimation) {
            return xxx;
          }).then((v) {
            // 消失的時候把狀態置為 false
        isLoading = false;
      });
    }
  }

  static void hideLoading(BuildContext context) {
    if (isLoading) {
      Navigator.of(context).pop();
    }
  }
}

複製程式碼

只提供了兩個靜態方法:showLoading()hideLoading()

showLoading 邏輯如下:

  1. 首先判斷 isLoading 是否為 true,如果正在顯示 loading,那麼則不作操作
  2. 如果不為 true,則顯示 loading,並把狀態置為 true
  3. 呼叫 then 方法,在 dialog 消失的時候把狀態置為 false

net_utils.dart

網路請求的管理&工具類。

在這個檔案中,我們要進行 Dio 的初始化和網路請求的封裝。

在檢視 API 文件的時候,發現登入狀態是由 Cookie 來管理的。 所以我要使用 cookie 的外掛來滿足需求。

寫一個初始化的方法,在 runApp 時呼叫:

static Dio _dio;

static void init() async {
   // 獲取沙盒路徑,用於儲存 cookie
  Directory tempDir = await getTemporaryDirectory();
  String tempPath = tempDir.path;
  CookieJar cj = PersistCookieJar(dir: tempPath);
  _dio = Dio(BaseOptions(baseUrl: 'http://127.0.0.1:3000'))
    ..interceptors.add(CookieManager(cj))
    ..interceptors.add(LogInterceptor(responseBody: true, requestBody: true));
}
複製程式碼

然後再寫一個通用的 _get() 方法,所有的網路請求最終都經過它:

static Future<Response> _get(BuildContext context, String url,
                             {Map<String, dynamic> params}) async {
  Loading.showLoading(context);
  try {
    return await _dio.get(url, queryParameters: params);
  } on DioError catch (e) {
    if (e.response is Map) {
      return Future.value(e.response);
    } else {
      return Future.error(0);
    }
  } finally {
    Loading.hideLoading(context);
  }
}
複製程式碼

這個邏輯我在上一篇文章中也提到過,如果返回狀態不是 2xx,那就會丟擲 DioError,然後我們在這裡處理邏輯即可。

common_text_style.dart

一些通用的 text 樣式。

我們在這裡建立一些 頂級變數

final commonTextStyle = TextStyle(fontSize: 16, color: Colors.black87);
final smallCommonTextStyle = TextStyle(fontSize: 12, color: Colors.black87);
final smallGrayTextStyle = TextStyle(fontSize: 12, color: Colors.grey);
複製程式碼

這樣其他類使用起來就很方便,萬一以後要改文字樣式也很方便。

總結

該篇文章是當前系列的第一篇,主要提供了一些搭建專案的思路。

該系列文章程式碼會傳至 GitHub:github.com/wanglu1209/…

並且每次提交都會對應一個分支。

本文中的程式碼請在 NeteaseCloudMusic-Day1 分支中檢視程式碼。

另我個人建立了一個「Flutter 交流群」,可以新增我個人微信 「17610912320」來入群。

Flutter實戰 | 從 0 搭建「網易雲音樂」APP(一、建立專案、新增外掛、通用程式碼)

相關文章