Flutter主题动态切换插件dynamic_theme_mode的使用

Flutter主题动态切换插件dynamic_theme_mode的使用

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  dynamic_theme_mode: ^1.0.0

使用

引入插件并配置初始主题模式

首先,引入 DynamicThemeMode 并将其作为 MaterialApp 的父级。传递一个初始的主题模式值。

import 'package:dynamic_theme_mode/dynamic_theme_mode.dart';

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  
  [@override](/user/override)
  Widget build(BuildContext context) {
    return DynamicThemeMode(
      initialThemeMode: ThemeMode.system, // 可以设置为 ThemeMode.light 或 ThemeMode.dark
      builder: (BuildContext context, ThemeMode themeMode) {
        return MaterialApp(
          theme: ThemeData(
            brightness: Brightness.light,
            primarySwatch: Colors.orange,
          ),
          darkTheme: ThemeData(
            brightness: Brightness.dark,
            primarySwatch: Colors.yellow,
          ),
          // 使用动态的主题模式
          themeMode: themeMode,
          home: ExampleHome(),
        );
      },
    );
  }
}

动态切换主题模式

可以使用 DynamicThemeMode.managerOf(context) 来改变当前主题模式。

DynamicThemeMode.managerOf(context)?.useDarkMode(); // 切换到暗色模式
// 或者
DynamicThemeMode.managerOf(context)?.setThemeMode(ThemeMode.light); // 切换到亮色模式

获取当前主题模式

获取当前应用的主题模式:

DynamicThemeMode.managerOf(context)?.themeMode;

示例代码

下面是完整的示例代码,展示如何使用 dynamic_theme_mode 插件来实现主题的动态切换。

import 'package:dynamic_theme_mode/dynamic_theme_mode.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(DynamicThemeMode(
    initialThemeMode: ThemeMode.system, // 设置初始主题模式
    builder: (context, themeMode) => ExampleApp(themeMode: themeMode), // 使用 ExampleApp
  ));
}

class ExampleApp extends StatelessWidget {
  const ExampleApp({
    Key? key,
    required this.themeMode, // 接收主题模式参数
  }) : super(key: key);

  final ThemeMode themeMode;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        brightness: Brightness.light,
        primarySwatch: Colors.orange,
        textTheme: ThemeData().textTheme.apply(
              displayColor: Colors.indigo,
            ),
      ),
      darkTheme: ThemeData(
        brightness: Brightness.dark,
        primarySwatch: Colors.yellow,
        textTheme: ThemeData().textTheme.apply(
              displayColor: Colors.red,
            ),
      ),
      themeMode: this.themeMode, // 使用动态主题模式
      home: ExampleHome(),
    );
  }
}

class ExampleHome extends StatelessWidget {
  const ExampleHome({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    final ThemeModeManager manager = DynamicThemeMode.managerOf(context);

    final buttonStyle = ElevatedButton.styleFrom(
      padding: const EdgeInsets.symmetric(horizontal: 30.0),
      fixedSize: Size.fromWidth(MediaQuery.of(context).size.width / 2.5),
    );

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text('DynamicThemeMode 示例'),
      ),
      body: Center(
        child: SizedBox(
          height: MediaQuery.of(context).size.height / 2,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Text(
                '${manager.themeMode}', // 显示当前主题模式
                style: Theme.of(context).textTheme.headline4,
              ),
              ElevatedButton(
                child: const Text('系统模式'),
                style: buttonStyle,
                onPressed: manager.useSystemMode, // 切换到系统模式
              ),
              ElevatedButton(
                child: const Text('亮色模式'),
                style: buttonStyle,
                onPressed: () => manager.setThemeMode(ThemeMode.light), // 切换到亮色模式
              ),
              ElevatedButton(
                child: const Text('暗色模式'),
                style: buttonStyle,
                onPressed: manager.useDarkMode, // 切换到暗色模式
              ),
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter主题动态切换插件dynamic_theme_mode的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter主题动态切换插件dynamic_theme_mode的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 dynamic_theme_mode 插件在 Flutter 中实现主题动态切换的代码示例。这个插件允许你轻松地管理应用的日间和夜间主题模式。

首先,确保你已经在 pubspec.yaml 文件中添加了 dynamic_theme 依赖:

dependencies:
  flutter:
    sdk: flutter
  dynamic_theme: ^3.0.1  # 请检查最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,你可以按照以下步骤实现主题动态切换:

  1. 定义主题数据

在你的 main.dart 文件中,首先定义两个主题(例如,日间和夜间主题):

import 'package:flutter/material.dart';
import 'package:dynamic_theme/dynamic_theme.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final ThemeData lightTheme = ThemeData(
    brightness: Brightness.light,
    primarySwatch: Colors.blue,
    // 其他主题配置...
  );

  final ThemeData darkTheme = ThemeData(
    brightness: Brightness.dark,
    primarySwatch: Colors.blueGrey,
    // 其他主题配置...
  );

  @override
  Widget build(BuildContext context) {
    return DynamicTheme(
      defaultBrightness: Brightness.light, // 默认亮度
      data: (brightness) {
        return brightness == Brightness.light ? lightTheme : darkTheme;
      },
      themedWidgetBuilder: (context, theme) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: theme,
          home: MyHomePage(),
          builder: (context, child) {
            // 包裹 MaterialApp 以处理状态重建(可选)
            return DynamicTheme.builder(
              theme: theme,
              builder: (context, widget) => widget!,
              child: child,
            );
          },
        );
      },
    );
  }
}
  1. 创建一个切换主题的按钮

在你的 MyHomePage 中,添加一个按钮来切换主题:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:dynamic_theme/dynamic_theme.dart';

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Theme Switcher Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              'Current Theme Mode: ${Theme.of(context).brightness == Brightness.light ? 'Light' : 'Dark'}',
              style: Theme.of(context).textTheme.headline4,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                DynamicTheme.of(context).setBrightness(
                  Theme.of(context).brightness == Brightness.light
                      ? Brightness.dark
                      : Brightness.light,
                );
              },
              child: Text('Switch Theme'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个例子中,我们使用了 DynamicTheme.of(context).setBrightness() 方法来切换主题的亮度。这会自动触发 DynamicTheme 小部件的重建,并应用新的主题。

  1. 持久化主题设置(可选)

如果你希望应用重启后仍然保持用户选择的主题,可以使用 shared_preferences 或其他存储机制来持久化主题设置。在启动时,根据存储的值设置初始主题。

这里是一个简单的例子,使用 shared_preferences 来持久化主题设置:

import 'package:shared_preferences/shared_preferences.dart';

// 在 MyApp 的 build 方法中添加以下代码来初始化主题
@override
Widget build(BuildContext context) {
  return FutureBuilder<SharedPreferences>(
    future: SharedPreferences.getInstance(),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        final SharedPreferences prefs = snapshot.data!;
        bool isDarkMode = prefs.getBool('isDarkMode') ?? false;

        return DynamicTheme(
          defaultBrightness: isDarkMode ? Brightness.dark : Brightness.light,
          data: (brightness) {
            return brightness == Brightness.light ? lightTheme : darkTheme;
          },
          themedWidgetBuilder: (context, theme) {
            return MaterialApp(
              title: 'Flutter Demo',
              theme: theme,
              home: MyHomePage(
                initialBrightness: brightness,
              ),
              builder: (context, child) {
                return DynamicTheme.builder(
                  theme: theme,
                  builder: (context, widget) => widget!,
                  child: child,
                );
              },
            );
          },
        );
      } else {
        return CircularProgressIndicator();
      }
    },
  );
}

// 在 MyHomePage 中添加对 SharedPreferences 的依赖和保存逻辑
class MyHomePage extends StatefulWidget {
  final Brightness initialBrightness;

  MyHomePage({Key? key, required this.initialBrightness}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Theme Switcher Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Current Theme Mode: ${Theme.of(context).brightness == Brightness.light ? 'Light' : 'Dark'}',
              style: Theme.of(context).textTheme.headline4,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                bool isDarkMode =
                    Theme.of(context).brightness == Brightness.dark;
                DynamicTheme.of(context).setBrightness(
                  isDarkMode ? Brightness.light : Brightness.dark,
                );

                final SharedPreferences prefs = await SharedPreferences.getInstance();
                prefs.setBool('isDarkMode', isDarkMode ? false : true);
              },
              child: Text('Switch Theme'),
            ),
          ],
        ),
      ),
    );
  }
}

以上代码展示了如何使用 dynamic_theme_mode 插件来实现主题动态切换,并持久化用户的主题选择。希望这对你有所帮助!

回到顶部