Flutter Web网站之最简方式实现暗黑主题无缝切换

简介: Flutter Web网站之最简方式实现暗黑主题无缝切换

往期


上期回顾


上期我们做了优化,主要针对ScrollView+GridView的使用场景,用了更加合适的组件,这期想做一个主题变更,为什么呢?

  • 第一 暗黑主题越来越刚需化,现在哪个主流App没有暗黑都不好意思上架,而ios阵营更加强硬的要求平台实现,否则下架,库克牛逼,我们惹不起。
  • 第二 项目还处于初期,这个时候重构改动成本较低
  • 第三 主题的变更网上有很多框架可以快速实现,但我想寻求的是最简单的实现,不想引入别人的框架,一来自己了如指掌,二来不用依赖别人的升级来满足未来奇葩的需求。 这期实现其实很简单,来往下看。

实现效果


大屏浅色

image.png

大屏暗黑

image.png

小屏浅色

image.png

小屏暗黑

image.png

代码实现


定义主题类AppTheme,用来配置不同的ThemeData

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浅色主题、浅色标题栏默认蓝色,这里我改成浅灰色

定义StreamController,用来动态变更数据

class ThemeBloc {
  // ignore: close_sinks
  final _themeStreamController = StreamController<AppTheme>();
  /// 变更主题调用方法
  get changeTheTheme => _themeStreamController.sink.add;
  /// 主题数据
  get themeData => _themeStreamController.stream;
}
final bloc = ThemeBloc();

给原来的MaterialApp包一层StreamBuilder

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,从而实现动态变更。如何触发变更数据呢?

image.png

如图设置页面添加了开关,代码如下

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来变更主题。 对变更主题就是这么简单,你是不是有疑问,我如何修改其他主题呢(如:文本,按钮,对话框等)

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内容。
  • 博客,这里考虑到有很多优秀的大佬,写过相关技术博客,帮你寻找最优秀的资源。功能设计如下图新增按钮。

image.png

结束


网站jetpack.net.cn,欢迎常来,也希望能在你学习Flutter的道路上提供一丢丢的帮助。



目录
相关文章
|
2月前
|
Web App开发 前端开发 JavaScript
Web开发者必收藏的10个实用网站,你还没收藏吗?
将这些网站收藏起来,定期访问,使它们成为您日常工作的一部分,助您在快速发展的 Web 开发领域保持领先。
128 2
Web开发者必收藏的10个实用网站,你还没收藏吗?
|
1月前
|
人工智能 搜索推荐 PHP
PHP在Web开发中的璀璨星辰:构建动态网站的幕后英雄###
【10月更文挑战第25天】 本文将带您穿越至PHP的宇宙,揭示其作为Web开发常青树的奥秘。通过生动实例与深入解析,展现PHP如何以简便、高效、灵活的姿态,赋能开发者打造动态交互式网站,同时不忘探讨其在新时代技术浪潮中面临的挑战与机遇,激发对技术创新与应用的无限思考。 ###
38 1
WK
|
1月前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
99 0
|
4月前
|
存储 前端开发 搜索推荐
Web前端网站(三)- 记事本
【8月更文挑战第8天】多种颜色搭配的动态粒子背景特效(粒子会随着鼠标的移动进行吸附,好看又好玩),左右摆动的文字特效,并且使用localStorage进行数据的持久化存储,使记事本的内容可以长期的保存在浏览器中,功能包括添加留言、显示留言、删除留言。每一行代码都有详细注释~~~大家可以尽情创作
73 5
Web前端网站(三)- 记事本
|
4月前
|
前端开发 搜索推荐 JavaScript
Web前端网站(四)- 音乐播放器
【8月更文挑战第9天】页面整体色调背景采用柔和渐变的方式呈现,与主页面的“毒药水式”色彩搭配形成了强烈的对比;周边花瓣缓缓飘落到水面之上形成涟漪。整体给人一种温馨、浪漫的感觉,还可以通过中间的3个按钮来控制音乐的切换和播放效果。每一行代码都有详细注释~~~大家可以尽情创作
52 2
Web前端网站(四)- 音乐播放器
|
4月前
|
Dart 前端开发 Java
|
4月前
|
前端开发 安全 JavaScript
PHP与现代Web开发:探索PHP在构建动态网站中的角色和优势
【8月更文挑战第29天】 在数字时代的浪潮下,PHP以其独特的灵活性、易用性以及强大的社区支持,持续成为Web开发领域的重要力量。本文将深入探讨PHP如何适应现代Web开发的需求,通过具体示例揭示PHP的实际应用,并分析其在面对新兴技术挑战时的应对策略。我们将一探究竟,PHP如何在众多编程语言中脱颖而出,成为许多开发者和企业的首选。
|
4月前
|
前端开发 JavaScript Android开发
Flutter 调用本地 web
Flutter 调用本地 web
48 0
|
6月前
|
监控 Serverless 持续交付
阿里云云效产品使用问题之如何让流水线支持构建 flutter web 应用到 OSS
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
6月前
|
存储 Apache 文件存储
在Apache环境下为Web网站增设访问控制:实战指南
在Apache服务器上保护网站资源涉及启用访问控制模块(`mod_authz_core`和`mod_auth_basic`),在`.htaccess`或`httpd.conf`中设定权限,如限制对特定目录的访问。创建`.htpasswd`文件存储用户名和密码,并使用`htpasswd`工具管理用户。完成配置后重启Apache服务,访问受限目录时需提供有效的用户名和密码。对于高安全性需求,可考虑更复杂的认证方法。【6月更文挑战第20天】
415 4