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月前
|
数据采集 Linux 数据库
Linux高级应用——web网站服务(2)
Linux高级应用——web网站服务(2)
38 0
|
26天前
|
数据采集 测试技术 网络安全
阿萨聊测试 ZAP3:如何测试HTTPS的Web网站?
阿萨聊测试 ZAP3:如何测试HTTPS的Web网站?
阿萨聊测试 ZAP3:如何测试HTTPS的Web网站?
|
28天前
|
存储 容器
Flutter 应用服务:主题、暗黑、国际化、本地化-app_service库
Flutter 应用服务:主题、暗黑、国际化、本地化-app_service库
48 0
|
28天前
|
Web App开发 Ubuntu 应用服务中间件
Flutter笔记:Web支持原理与实践
Flutter笔记:Web支持原理与实践
64 0
|
28天前
Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例
Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例
30 0
|
28天前
|
Dart 小程序 前端开发
WebSocket 解析与应用(包含web前端、服务端、小程序、dart/flutter中的用法)
WebSocket 解析与应用(包含web前端、服务端、小程序、dart/flutter中的用法)
123 0
|
1月前
|
Oracle Java 关系型数据库
JSP网站常见的Web服务器是什么
JSP网站常见的Web服务器是什么,JSP网站常见的Web服务器有很多,以下是其中比较常见的几种
18 0
|
1月前
|
Ubuntu 网络协议 Apache
【cpolar】Ubuntu本地快速搭建web小游戏网站,公网用户远程访问
【cpolar】Ubuntu本地快速搭建web小游戏网站,公网用户远程访问
52 0
|
2月前
|
存储 前端开发 Java
基于WEB的电子产品商城网站的设计与实施
基于WEB的电子产品商城网站的设计与实施
|
2月前
|
域名解析 安全 Linux
Web网站服务
Web网站服务
25 0

相关产品

  • 云迁移中心