Flutter Web網站之最簡方式實現暗黑主題無縫切換

往期

上期回顧

上期咱們作了優化,主要針對ScrollView+GridView的使用場景,用了更加合適的組件,這期想作一個主題變動,爲何呢?ios

  • 第一 暗黑主題愈來愈剛需化,如今哪一個主流App沒有暗黑都很差意思上架,而ios陣營更增強硬的要求平臺實現,不然下架,庫克牛逼,咱們惹不起。
  • 第二 項目還處於初期,這個時候重構改動成本較低
  • 第三 主題的變動網上有不少框架能夠快速實現,但我想尋求的是最簡單的實現,不想引入別人的框架,一來本身瞭如指掌,二來不用依賴別人的升級來知足將來奇葩的需求。 這期實現其實很簡單,來往下看。

實現效果

大屏淺色git

大屏暗黑
小屏淺色
小屏暗黑

代碼實現

定義主題類AppTheme,用來配置不一樣的ThemeDatagithub

class AppTheme {

  ThemeData themeData;

  AppTheme(this.themeData);

  // ignore: non_constant_identifier_names
  static final AppTheme DARK_THEME = AppTheme(ThemeData.dark());

  // ignore: non_constant_identifier_names
  static final AppTheme LIGHT_THEME = AppTheme(
      ThemeData(brightness: Brightness.light, primaryColor: Colors.grey[50]));
}
複製代碼

DARK_THEME暗黑主題 LIGHT_THEME淺色主題、淺色標題欄默認藍色,這裏我改爲淺灰色canvas

定義StreamController,用來動態變動數據bash

class ThemeBloc {
  // ignore: close_sinks
  final _themeStreamController = StreamController<AppTheme>();
  /// 變動主題調用方法
  get changeTheTheme => _themeStreamController.sink.add;
  /// 主題數據
  get themeData => _themeStreamController.stream;
}

final bloc = ThemeBloc();
複製代碼

給原來的MaterialApp包一層StreamBuilderapp

StreamBuilder<AppTheme>(
        initialData: AppTheme.LIGHT_THEME,
        stream: bloc.themeData,
        builder: (context, AsyncSnapshot<AppTheme> snapshot) {
          return MaterialApp(
            title: 'Jetpack',
            theme: snapshot.data.themeData,
            home: PageHome(),
            routes: <String, WidgetBuilder>{
              "/qq": (context) => PageQQLink(),
              "/pageChatGroup": (context) => PageChatGroup(),
            },
          );
        })
複製代碼

initialData 默認數據 stream 將bloc.themeData賦值給它,用來監聽數據變化 snapshot 數據變化的快照,最終交給MaterialApp的theme,從而實現動態變動。如何觸發變動數據呢? 框架

如圖設置頁面添加了開關,代碼以下

SwitchListTile(
          secondary: Icon(_isEnabled ? Icons.brightness_4 : Icons.brightness_5),
          title: Text("暗黑主題"),
          subtitle: Text("將主題調成暗黑色"),
          value: _isEnabled,
          onChanged: (value) {
            setState(() {
              _isEnabled = value;
            });
            if (value) {
              bloc.changeTheTheme(AppTheme.DARK_THEME);
            } else {
              bloc.changeTheTheme(AppTheme.LIGHT_THEME);
            }
          },
        )
複製代碼

這裏調用bloc.changeTheTheme來變動主題。 對變動主題就是這麼簡單,你是否是有疑問,我如何修改其餘主題呢(如:文本,按鈕,對話框等)ide

ThemeData

再看下我得實現學習

static final AppTheme LIGHT_THEME = AppTheme(
      ThemeData(brightness: Brightness.light, primaryColor: Colors.grey[50]));
複製代碼

我這裏修改了brightness、primaryColor,其實它還有不少,請看優化

ThemeData({
    Brightness brightness,
    VisualDensity visualDensity,
    MaterialColor primarySwatch,
    Color primaryColor,
    Brightness primaryColorBrightness,
    Color primaryColorLight,
    Color primaryColorDark,
    Color accentColor,
    Brightness accentColorBrightness,
    Color canvasColor,
    Color scaffoldBackgroundColor,
    Color bottomAppBarColor,
    Color cardColor,
    Color dividerColor,
    Color focusColor,
    Color hoverColor,
    Color highlightColor,
    Color splashColor,
    InteractiveInkFeatureFactory splashFactory,
    Color selectedRowColor,
    Color unselectedWidgetColor,
    Color disabledColor,
    Color buttonColor,
    ButtonThemeData buttonTheme,
    ToggleButtonsThemeData toggleButtonsTheme,
    Color secondaryHeaderColor,
    Color textSelectionColor,
    Color cursorColor,
    Color textSelectionHandleColor,
    Color backgroundColor,
    Color dialogBackgroundColor,
    Color indicatorColor,
    Color hintColor,
    Color errorColor,
    Color toggleableActiveColor,
    String fontFamily,
    TextTheme textTheme,
    TextTheme primaryTextTheme,
    TextTheme accentTextTheme,
    InputDecorationTheme inputDecorationTheme,
    IconThemeData iconTheme,
    IconThemeData primaryIconTheme,
    IconThemeData accentIconTheme,
    SliderThemeData sliderTheme,
    TabBarTheme tabBarTheme,
    TooltipThemeData tooltipTheme,
    CardTheme cardTheme,
    ChipThemeData chipTheme,
    TargetPlatform platform,
    MaterialTapTargetSize materialTapTargetSize,
    bool applyElevationOverlayColor,
    PageTransitionsTheme pageTransitionsTheme,
    AppBarTheme appBarTheme,
    BottomAppBarTheme bottomAppBarTheme,
    ColorScheme colorScheme,
    DialogTheme dialogTheme,
    FloatingActionButtonThemeData floatingActionButtonTheme,
    NavigationRailThemeData navigationRailTheme,
    Typography typography,
    CupertinoThemeData cupertinoOverrideTheme,
    SnackBarThemeData snackBarTheme,
    BottomSheetThemeData bottomSheetTheme,
    PopupMenuThemeData popupMenuTheme,
    MaterialBannerThemeData bannerTheme,
    DividerThemeData dividerTheme,
    ButtonBarThemeData buttonBarTheme,
  }
複製代碼

這裏面得主題你均可以修改,你是否是看到了 AppBarTheme、DialogTheme、TextTheme、BottomSheetThemeData等等,不用我解釋了吧,你應該知道是誰得樣式了吧。

總結

20幾行新增得代碼就搞定了,爲何還要用別人得框架呢?是吧。

囉嗦一句

計劃真的是趕不上變化,不急,慢慢完善哈。

源碼

請轉github代碼查看完整實現

ToDo

該部份內容後期慢慢給你們更新,請客觀不要着急,固然你能夠參與進來,私聊我就行哦。

  • 示例部準備下期實現,跳轉至詳情頁面,並展現用例。源碼已經完成點擊便可跳轉至github。
  • Tags 部分下期實現,這部分也須要新的UI展示,標籤的功能相似與搜索,提供更快捷的方式查找想要的功能。
  • 留言功能設計,在大家使用過程當中確定會有不一樣的建議,有了這個功能就能知道大家的心聲,因此這也是咱們須要的實現的一個功能。
  • 優秀的項目推薦,有不少優秀的項目等待着咱們去發現,我一我的的能力有限,若是有更多的人來推薦,會不斷豐富咱們的Jetpack內容。
  • 博客,這裏考慮到有不少優秀的大佬,寫過相關技術博客,幫你尋找最優秀的資源。功能設計以下圖新增按鈕。

結束

網站jetpack.net.cn,歡迎常來,也但願能在你學習Flutter的道路上提供一丟丟的幫助。

相關文章
相關標籤/搜索