Flutter實戰 | 從 0 搭建「網易雲音樂」APP(1、建立項目、添加插件、通用代碼)

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

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

由於工做的緣由,一星期有可能只更新一篇該系列的文章,不過一星期最少一篇。微信

本章節爲第一節,從建立項目提及。cookie

建立「網易雲音樂」項目

首先看一下本地 Flutter 環境:網絡

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

項目建立好後,刪除無用代碼,而後開始建立文件夾:ide

一共分爲六個文件夾:工具

  • model:存放全部數據類
  • pages:存放全部的頁面
  • provider:存放全部的 Provider
  • route:存放路由相關
  • utils:存放全部的工具類
  • widgets:存放全部封裝好的組件

下面咱們開始添加依賴。post

添加插件

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

例如 網絡請求確定有,那我會選擇 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 擴展

通用代碼

功能以下:

插件 做用
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」來入羣。

相關文章
相關標籤/搜索