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的道路上提供一丢丢的帮助。

相关文章
相关标签/搜索