• Flutter 中优雅切换应用主题的组件


    Flutter 中优雅切换应用主题的组件

    视频

    https://youtu.be/L–XLpc452I

    https://www.bilibili.com/video/BV1wD421n75p/

    前言

    原文 https://ducafecat.com/blog/flutter-app-theme-switch

    adaptive_theme

    Adaptive Theme 这个组件通过包裹 MaterialApp 的方式整体管理 theme 主题,实现如下功能:

    • 切换 light、dark、system 三种模式
    • 自定义色彩
    • 保存主题选择
    • 开启调试按钮

    参考

    https://pub.dev/packages/adaptive_theme

    https://flutter.ducafecat.com/pubs/adaptive_theme-package-info

    https://github.com/birjuvachhani/adaptive_theme

    步骤

    安装配置

    https://pub.dev/packages/adaptive_theme

    pubspec.yaml

    dependencies:
      flutter:
        sdk: flutter
        
      adaptive_theme: ^3.6.0
    
    • 1
    • 2
    • 3
    • 4
    • 5

    lib/main.dart

    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      
      Widget build(BuildContext context) {
        return AdaptiveTheme(
          light: ThemeData.light(useMaterial3: true),
          dark: ThemeData.dark(useMaterial3: true),
          initial: AdaptiveThemeMode.light,
          debugShowFloatingThemeButton: true,
          builder: (theme, darkTheme) => MaterialApp(
            title: 'Flutter Demo',
            theme: theme,
            darkTheme: darkTheme,
            home: const MyHomePage(title: 'Flutter Demo Home Page'),
          ),
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    debugShowFloatingThemeButton 开启调试按钮

    设置主题

    设置亮色

    ElevatedButton(
      onPressed: () {
        AdaptiveTheme.of(context).setLight();
      },
      child: const Text('Set Light Theme'),
    ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    设置暗色

    ElevatedButton(
      onPressed: () {
        AdaptiveTheme.of(context).setDark();
      },
      child: const Text('Set Dark Theme'),
    ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    设置系统

    ElevatedButton(
      onPressed: () {
        AdaptiveTheme.of(context).setSystem();
      },
      child: const Text('Set System Theme'),
    ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    toggle 切换

    ElevatedButton(
      onPressed: () {
        AdaptiveTheme.of(context).toggleThemeMode();
      },
      child: const Text('Toggle Theme Mode'),
    ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    重置样式

    ElevatedButton(
      onPressed: () {
        AdaptiveTheme.of(context).reset();
      },
      child: const Text('Reset Theme'),
    ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    监听样式切换

    // 监听当前样式
    ValueListenableBuilder(
      valueListenable: AdaptiveTheme.of(context).modeChangeNotifier,
      builder: (_, mode, child) {
        return Text(mode.modeName);
      },
    ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    自定义样式颜色

    ElevatedButton(
      onPressed: () {
        AdaptiveTheme.of(context).setTheme(
          light: ThemeData(
            useMaterial3: true,
            brightness: Brightness.light,
            colorSchemeSeed: Colors.green,
          ),
          dark: ThemeData(
            useMaterial3: true,
            brightness: Brightness.dark,
            colorSchemeSeed: Colors.brown,
          ),
        );
      },
      child: const Text('Change Theme Color'),
    ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    读取配置

    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      final savedThemeMode = await AdaptiveTheme.getThemeMode();
      runApp(MyApp(savedThemeMode: savedThemeMode));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    class MyApp extends StatelessWidget {
      final AdaptiveThemeMode? savedThemeMode;
    
      const MyApp({super.key, this.savedThemeMode});
    
      // This widget is the root of your application.
      
      Widget build(BuildContext context) {
        return AdaptiveTheme(
          light: ThemeData.light(useMaterial3: true),
          dark: ThemeData.dark(useMaterial3: true),
          initial: savedThemeMode ?? AdaptiveThemeMode.light,
          debugShowFloatingThemeButton: true,
          builder: (theme, darkTheme) => MaterialApp(
            title: 'Flutter Demo',
            theme: theme,
            darkTheme: darkTheme,
            home: const MyHomePage(title: 'Flutter Demo Home Page'),
          ),
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    不要覆盖 key

    本地离线采用 shared_preferences 组件,所以不要覆盖键值 adaptive_theme_preferences

    https://github.com/BirjuVachhani/adaptive_theme/blob/main/lib/src/adaptive_theme.dart

      /// Key used to store theme information into shared-preferences. If you want
      /// to persist theme mode changes even after shared-preferences
      /// is cleared (e.g. after log out), do not remove this [prefKey] key from
      /// shared-preferences.
      static const String prefKey = 'adaptive_theme_preferences';
    
    • 1
    • 2
    • 3
    • 4
    • 5

    代码

    https://github.com/ducafecat/flutter_develop_tips/tree/main/flutter_application_adaptive_theme

    小结

    通过使用 Flutter 的 adaptive_theme 组件,我们可以轻松地实现应用主题的切换功能。该组件提供了简单的方法来手动设置浅色或深色主题,并且还可以根据系统定义的主题进行自适应切换。无论是在用户界面上还是在代码层面上,我们可以灵活地控制应用程序的主题外观,为用户提供更好的体验。

    感谢阅读本文

    如果有什么建议,请在评论中让我知道。我很乐意改进。


    flutter 学习路径

    • Flutter 优秀插件推荐 https://flutter.ducafecat.com
    • Flutter 基础篇1 - Dart 语言学习 https://ducafecat.com/course/dart-learn
    • Flutter 基础篇2 - 快速上手 https://ducafecat.com/course/flutter-quickstart-learn
    • Flutter 实战1 - Getx Woo 电商APP https://ducafecat.com/course/flutter-woo
    • Flutter 实战2 - 上架指南 Apple Store、Google Play https://ducafecat.com/course/flutter-upload-apple-google
    • Flutter 基础篇3 - 仿微信朋友圈 https://ducafecat.com/course/flutter-wechat
    • Flutter 实战3 - 腾讯 tim 即时通讯开发 https://ducafecat.com/course/flutter-tim

    © 猫哥
    ducafecat.com

    end

  • 相关阅读:
    顺寻查找(C语言)
    Flutter 笔记 | Flutter 事件与通知
    前端研习录(09)——CSS浮动与清除浮动
    SSM出租车查询系统毕业设计-附源码220915
    VUE条件渲染
    windbg查看模块中的方法时报错no code found
    单调栈——包含min函数的栈
    智能出价策略如何影响广告效果?
    vue input防抖
    error: #20: identifier “PWMC_Handle_t“ is undefined
  • 原文地址:https://blog.csdn.net/weixin_42320543/article/details/138170906