Flutter主题管理插件playx_theme的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter主题管理插件playx_theme的使用

Playx Theme: 轻松控制您的应用视觉风格。无缝切换主题,享受平滑动画,并轻松为每个主题定义自定义颜色方案。

特性

  • 简易主题管理: 轻松创建和管理应用主题。
  • 平滑过渡: 使用独特的过渡效果在主题之间切换。
  • 自定义颜色: 为每个主题定义自定义颜色,例如 context.playxColors.primary
  • 自动主题持久化: 自动存储并加载上次使用的主题。
  • 实用小部件: 使用自定义实用小部件增强主题功能。

安装

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

dependencies:
  playx_theme: ^1.0.2

使用

启动PlayxTheme

在运行应用之前初始化并启动主题。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 启动AppTheme
  await PlayxTheme.boot(
    config: PlayxThemeConfig(
      themes: [
        XTheme(
          id: 'light',
          name: 'Light',
          themeData: ThemeData.light(),
        ),
        XTheme(
          id: 'dark',
          name: 'Dark',
          themeData: ThemeData.dark(),
        ),
      ],
    ),
  );

  // 运行应用
  runApp(const MyApp());
}

将应用包装在PlayXThemeBuilder中

使用 PlayXThemeBuilder 包装应用以应用主题。

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

  @override
  Widget build(BuildContext context) {
    return PlayXThemeBuilder(
      builder: (context, theme) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: theme.themeData,
          home: const HomeScreen(),
        );
      },
    );
  }
}

更新应用主题

通过 PlayxTheme 切换主题。

FloatingActionButton(
  onPressed: () {
    PlayxTheme.updateById('dark');
  },
  child: Icon(
    Icons.next,
    color: PlayxTheme.colorScheme.onBackground,
  ),
)

访问当前主题

使用上下文扩展获取当前主题信息。

final themeId = context.xTheme.id;

// 旧版访问
final currentThemeId = PlayxTheme.currentTheme.id;
final currentThemeData = PlayxTheme.currentThemeData;

可用方法

方法 描述
index 返回当前主题索引。
id 返回当前主题ID。
name 返回当前主题名称。
currentTheme 返回当前 XTheme
currentThemeData 返回当前 ThemeData
colors 返回当前 XTheme 颜色。
initialTheme 返回起始主题(如果提供)。
supportedThemes 返回配置在 PlayxThemeConfig 中的主题列表。
next 更新应用主题到下一个主题。
updateByIndex 通过索引更新应用主题。
updateTo 更新应用主题到特定 XTheme
updateById 通过特定主题ID更新应用主题。
isDeviceInDarkMode 确定设备是否处于暗模式或亮模式。
updateToLightMode 更新应用主题到第一个亮模式主题。
updateToDarkMode 更新应用主题到第一个暗模式主题。
updateToDeviceMode 更新应用主题到设备模式。
updateByThemeMode 更新应用主题到与给定模式匹配的第一个主题。
clearLastSavedTheme 清除上次保存的主题。

动画

Playx主题包提供了多种动画来增强主题切换体验。

PlayxThemeSwitchingArea

为了在更改主题时显示动画,请将相关屏幕包装在 PlayxThemeSwitchingArea 中。

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

  @override
  Widget build(BuildContext context) {
    return PlayxThemeSwitchingArea(
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Playx Theme Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text('You have pushed the button this many times:'),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => PlayxTheme.next(),
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

主题切换动画控制

使用 PlayxThemeAnimation 类及其子类自定义主题切换动画。您可以控制动画的各种方面。

PlayxThemeAnimation

主题动画的基本类提供常见设置,包括:

  • isReversed: 反转动画方向。
  • onAnimationFinish: 动画完成时触发的回调。
  • duration: 动画持续时间。
PlayxThemeClipperAnimation

定义基于剪切的动画,并带有自定义剪切器设置。

PlayxThemeAnimation.clipper(
  clipper: const ThemeSwitcherCircleClipper(),
  offset: Offset.zero,
)

您可以使用 PlayxThemeSwitcher 从触发小部件开始动画切换主题。

PlayxThemeSwitcher(
  builder: (ctx, theme) => FloatingActionButton(
    onPressed: () {
      PlayxTheme.next(
        animation: PlayxThemeAnimation.clipper(
          clipper: const ThemeSwitcherCircleClipper(),
          context: ctx,
        ),
      );
    },
    tooltip: 'Next Theme',
    child: Icon(
      Icons.add,
      color: context.colorScheme.onPrimary,
    ),
  ),
);

这将在 FloatingActionButton 上使用一个圆形剪切动画开始切换主题。

PlayxThemeFadeAnimation

控制渐变效果,具有可调的不透明度级别。

PlayxThemeAnimation.fade(
  begin: 0.0,
  end: 1.0,
)
PlayxThemeScaleAnimation

处理缩放效果,具有可调的缩放值。

PlayxThemeAnimation.scale(
  begin: 0.5,
  end: 1.0,
)
PlayxThemeHorizontalSlideAnimation

创建水平滑动效果,具有起始和结束偏移量。

PlayxThemeAnimation.horizontalSlide(
  beginOffset: Offset(-1.0, 0.0),
  endOffset: Offset(0.0, 0.0),
)
PlayxThemeVerticalSlideAnimation

创建垂直滑动效果,具有起始和结束偏移量。

PlayxThemeAnimation.verticalSlide(
  beginOffset: Offset(0.0, -1.0),
  endOffset: Offset(0.0, 0.0),
)

自定义主题

创建 PlayxThemeConfig 对象并传递给 PlayxTheme.boot() 来自定义主题。

final config = PlayxThemeConfig(
  themes: [
    XTheme(
      id: 'light',
      name: 'Light',
      themeData: ThemeData(
        brightness: Brightness.light,
        colorScheme: lightColors.colorScheme,
        useMaterial3: true,
      ),
      cupertinoThemeData: const CupertinoThemeData(
        brightness: Brightness.light,
      ),
      colors: lightColors,
    ),
    XTheme.builder(
      id: 'dark',
      name: 'Dark',
      initialTheme: ThemeData(
        brightness: Brightness.dark,
        colorScheme: darkColors.colorScheme,
        useMaterial3: true,
      ),
      themeBuilder: (locale) => ThemeData(
        brightness: Brightness.dark,
        colorScheme: darkColors.colorScheme,
        useMaterial3: true,
      ),
      cupertinoThemeBuilder: (locale) => const CupertinoThemeData(
        brightness: Brightness.dark,
      ),
      isDark: true,
      colors: darkColors,
    ),
  ],
  initialThemeIndex: PlayxTheme.isDeviceInDarkMode() ? 1 : 0,
);

自定义主题颜色

通过扩展 PlayxColors 创建每个主题的自定义颜色。

class LightColors extends PlayxColors{
  @override
  Color get background => XColors.white;
  
  @override
  Color get error => XColors.red;
  
  @override
  Color get onBackground => XColors.black;
}

在小部件树中使用自定义颜色。

ColoredBox(color: context.playxColors.primary);

扩展 PlayxColors 添加更多颜色。

abstract class AppColors extends PlayxColors{
  Color get containerBackgroundColor;
  static const Color blue = Colors.blue;
}

class LightColorScheme extends AppColors {
  @override
  Color get containerBackgroundColor => XColors.white;
  
  @override
  Color get background => XColors.white;
  
  @override
  Color get error => XColors.red;
  
  @override
  Color get onBackground => XColors.black;
}

访问扩展的颜色。

static AppColors of(BuildContext context) => context.playxColors as AppColors;

final primary = AppColors.of(context).primary;

extension AppColorsExtension on BuildContext {
  AppColors get colors => AppColors.of(this);
}

ColoredBox(color: context.colors.primary);

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

1 回复

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


当然,以下是如何在Flutter项目中使用playx_theme插件进行主题管理的代码示例。playx_theme是一个用于管理和切换应用主题的插件,它允许你轻松地实现白天和黑夜模式的切换。

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

dependencies:
  flutter:
    sdk: flutter
  playx_theme: ^最新版本号 # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中配置playx_theme

1. 配置主题数据

lib目录下创建一个新的Dart文件,例如themes.dart,用于定义你的主题数据:

// themes.dart
import 'package:flutter/material.dart';
import 'package:playx_theme/playx_theme.dart';

final LightTheme lightTheme = LightTheme(
  colorScheme: ColorScheme.light(
    primary: Colors.blue,
    onPrimary: Colors.white,
    secondary: Colors.amber,
    onSecondary: Colors.black,
    background: Colors.white,
    onBackground: Colors.black,
    surface: Colors.white,
    onSurface: Colors.black,
  ),
  textTheme: TextTheme(
    bodyText1: TextStyle(color: Colors.black, fontSize: 16),
    bodyText2: TextStyle(color: Colors.grey, fontSize: 14),
    // 其他文本样式...
  ),
  // 其他主题配置...
);

final DarkTheme darkTheme = DarkTheme(
  colorScheme: ColorScheme.dark(
    primary: Colors.blue.shade900,
    onPrimary: Colors.white,
    secondary: Colors.amber.shade900,
    onSecondary: Colors.white,
    background: Colors.black,
    onBackground: Colors.white,
    surface: Colors.black,
    onSurface: Colors.white,
  ),
  textTheme: TextTheme(
    bodyText1: TextStyle(color: Colors.white, fontSize: 16),
    bodyText2: TextStyle(color: Colors.grey.shade400, fontSize: 14),
    // 其他文本样式...
  ),
  // 其他主题配置...
);

final ThemeData defaultTheme = ThemeData.from(
  lightTheme: lightTheme,
  darkTheme: darkTheme,
);

2. 使用PlayxTheme包装你的应用

在你的main.dart文件中,使用PlayxTheme包装你的应用:

// main.dart
import 'package:flutter/material.dart';
import 'package:playx_theme/playx_theme.dart';
import 'themes.dart'; // 导入你定义的主题文件

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return PlayxTheme(
      initialThemeMode: ThemeMode.system, // 初始主题模式,可以是system, light, dark
      themes: {
        ThemeMode.light: defaultTheme.copyWith(brightness: Brightness.light),
        ThemeMode.dark: defaultTheme.copyWith(brightness: Brightness.dark),
      },
      builder: (context, theme) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: theme,
          home: MyHomePage(),
        );
      },
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final themeService = ThemeService.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Theme Management'),
      ),
      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: () {
                themeService.setThemeMode(ThemeMode.light);
              },
              child: Text('Switch to Light Mode'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                themeService.setThemeMode(ThemeMode.dark);
              },
              child: Text('Switch to Dark Mode'),
            ),
          ],
        ),
      ),
    );
  }
}

3. 运行应用

现在,你可以运行你的Flutter应用,并应该能够看到主题切换的按钮。点击这些按钮将切换应用的主题模式。

注意事项

  • 确保你的应用遵循Material Design规范,以便主题切换效果最佳。
  • 你可以根据需要自定义更多的主题配置,例如TypographyShape等。
  • 你可以监听系统主题变化并相应地更新你的应用主题,这可以通过ThemeService提供的监听功能实现。

以上就是在Flutter中使用playx_theme插件进行主题管理的代码示例。希望这对你有所帮助!

回到顶部