談談Flutter適配深色模式

建古發表於2021-05-29

一、前言 現在app適配深色模式都是主流了,也因為專案剛開始,所以打算一開始就把深色模式考慮進去,不一定要用,但至少要留好口子,以便以後來了個需求,就會各種繁瑣,各種判斷之類的。所以就有了全域性深色模式的嘗試。以下的實現是我自己的看法和設計。如有不合之處,請指出!謝謝!

二、需求 因為顏色是統一配置的,所以我只想簡單的一個顏色類呼叫定義的顏色就達到顏色適配的效果。不想在元件設定顏色的地方來判斷是否是深色模式,然後設定對應顏色,這樣會特別繁瑣,也怕有遺漏的地方。後期維護的時候也特別麻煩。當然flutter本來就有很多主題設定,可以設定元件的是否什麼顏色,但是總有地方還需要自己來適配的。所以我就做了一個這樣的方案。

先看效果: 在這裡插入圖片描述

在這裡插入圖片描述

三、具體實現(這邊使用GetX來實現切換深色模式,也可以用其他設定,但顏色類是這樣的。不管用什麼方式都可以。)

1、建立一個顏色類:

class FXColor {
  /// 主色
  static get mainBg {
    return FXColorConfig.getColor(FXColorConfig.main_bg_key);
  }
}
複製程式碼

2、外部呼叫

appBar: AppBarWidget(
        '首頁詳情',
        context: context,
        backgroundColor: FXColor.mainBg, // 就這樣呼叫 這樣既可
        titleColor: FXColor.title,
      ),
複製程式碼

三、具體實現

/// 顏色類適配黑暗模式 三步驟 1 2 3 ,一般來說一個app的樣式,不會太多,所以這邊處理就可以達到全域性設定。
/// 適配黑暗模式步驟 新增之前可先檢視是否已經新增該樣式
/// 1 FXColorConfig類中新增顏色key, 例 static const String main_bg_key = 'main_bg';
/// 2 FXColorConfig類中的_colors集合中新增顏色key-value
///   例:main_bg_key: [FXColor.whiteColor, FXColor.colorText33],
///   key:main_bg_key是步驟1新增的key, value:陣列 兩個顏色值,0是正常模式顏色,1是黑暗模式顏色
/// 3 FXColor類新增get方法 對外訪問
///   例 static get mainBg {
//        return FXColorConfig.getColor(FXColorConfig.main_bg_key);
//       }
複製程式碼

FXColorConfig類和FXColor類的全部實現

//對外呼叫
class FXColor {
  /// 主色
  static get mainBg {
    return FXColorConfig.getColor(FXColorConfig.main_bg_key);
  }

  /// title 標題
  static get title {
    return FXColorConfig.getColor(FXColorConfig.title_key);
  }

  /// subTitle 副標題
  static get subTitle {
    return FXColorConfig.getColor(FXColorConfig.sub_title_key);
  }

  /// content 內容
  static get content {
    return FXColorConfig.getColor(FXColorConfig.content_key);
  }

  /// buttonBg 按鈕背景
  static get buttonBg {
    return FXColorConfig.getColor(FXColorConfig.button_bg_key);
  }

  /// buttonTitle 按鈕標題
  static get buttonTitle {
    return FXColorConfig.getColor(FXColorConfig.button_title_key);
  }

  /// buttonTitle 按鈕標題
  static get divider {
    return FXColorConfig.getColor(FXColorConfig.divider_key);
  }

///常用顏色值
  /// 透明
  static const Color colorTransparent = Colors.transparent;

  /// 主檢視背景色
  static Color colorBackground =
      Get.isDarkMode ? Color(0xFFFFFFFF) : Color(0xFF2268F2);

  ///導航欄背景顏色
  static const Color color_nav_bar_bg = Color(0xFFFFFFFF);

  ///主要 分割線
  static const Color color_divider = Color(0xFFEDEDED);

  /// 進度顏色
  static const Color color_progress = Color(0xFFE6E7E9);

  /// 文字顏色
  static const Color color_text_33 = Color(0xFF333333);

  /// 文字顏色
  static const Color color_text_66 = Color(0xFFE6E7E9);

  /// 文字顏色
  static const Color color_text_99 = Color(0xFF999999);

  /// 文字顏色
  static const Color color_text_hint = Color(0xFFE6E7E9);

  /// 紅色
  static const Color red_color = Color(0xFFFF3622);

  ///藍色
  static const Color blue_color = Color(0xFF2268F2);

  ///白色
  static const Color white_color = Color(0xFFFFFFFF);

  /// 黑色
  static const Color black_color = Color(0xFF000000);

  ///綠色
  static const Color green_color = Color(0xFF06C88C);

  ///黃色
  static const Color yellow_color = Color(0xFFF5A623);
}
複製程式碼
/// 顏色配置 
class FXColorConfig {
  /// 顏色key
  static const String main_bg_key = 'main_bg';
  static const String title_key = 'title';
  static const String sub_title_key = 'sub_title';
  static const String content_key = 'content';
  static const String button_bg_key = 'button_bg';
  static const String button_title_key = 'button_title';
  static const String divider_key = 'divider';

  /// 顏色值
  static const _colors = {
    main_bg_key: [FXColor.white_color, FXColor.color_text_33],
    title_key: [FXColor.color_text_33, FXColor.white_color],
    sub_title_key: [FXColor.color_text_33, FXColor.white_color],
    content_key: [FXColor.color_text_33, FXColor.white_color],
    button_bg_key: [FXColor.red_color, FXColor.yellow_color],
    button_title_key: [FXColor.color_text_33, FXColor.white_color],
    divider_key: [FXColor.color_text_33, FXColor.white_color],
  };

  /// 取顏色值
  static Color getColor(String key) {
    final colors = _colors[key];
    if (colors == null) {
      return FXColor.color_text_33;
    }

    if (Get.isDarkMode == true) {
      if (colors.length == 2) {
        return colors[1];
      } else {
        return colors[0];
      }
    } else {
      return colors[0];
    }
  }
}
複製程式碼

最後建立一個設定是否深色模式的類 ThemeConfig

///主題色配置 統一配置
class ThemeConfig {
  /// 正常模式主題設定
  static ThemeData lightTheme = ThemeData(brightness: Brightness.light);

  /// 黑暗模式主題設定
  static ThemeData darkTheme = ThemeData(brightness: Brightness.dark);

  ///設定黑暗模式
  static void changeThemeMode({ThemeMode themeMode = ThemeMode.system}) {
    /// 主題型別
    Get.changeThemeMode(themeMode);

    /// 注意樣式設定
//    switch (themeMode) {
//      case ThemeMode.system:
//        if (Get.isDarkMode == true) {
//          Get.changeTheme(darkTheme);
//        } else {
//          Get.changeTheme(lightTheme);
//        }
//        break;
//      case ThemeMode.dark:
//        Get.changeTheme(darkTheme);
//        break;
//      case ThemeMode.light:
//        Get.changeTheme(lightTheme);
//        break;
//    }
  }
}
複製程式碼

呼叫:

/// 正常模式
ThemeConfig.changeThemeMode(themeMode: ThemeMode.light);

/// 深色模式
ThemeConfig.changeThemeMode(themeMode: ThemeMode.dark);
複製程式碼

四、後續 深色模式就以上的全部實現,對此多語言設定應該也可以同樣的思路來解決。後續會繼續寫個多語言適配。

記錄程式碼,記錄生活...

相關文章