Flutter色彩方案管理插件flex_color_scheme的使用

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

Flutter色彩方案管理插件flex_color_scheme的使用

简介

FlexColorScheme 是一个用于创建美丽Flutter Material Design主题的插件。它支持Material-3生成的颜色方案,提供完整的ThemeData对象,并具有许多附加功能。你可以选择预定义的设计或自定义自己的设计,还可以轻松配置组件主题。

主要特点

  • 完整UI组件着色:确保所有Flutter SDK UI组件都由其ColorScheme和自定义颜色着色。
  • Material-3支持:默认启用Material-3模式,提供与Material-3一致的颜色结果和样式。
  • 高级着色特性:如表面Alpha混合、多种子颜色等。
  • 组件主题定制:通过简单的属性值调整UI组件的样式,如边框半径等。

快速开始

安装

在你的项目中添加 flex_color_scheme 包:

flutter pub add flex_color_scheme

然后导入包:

import 'package:flex_color_scheme/flex_color_scheme.dart';

使用预定义颜色方案

你可以使用内置的55种颜色方案之一。这里以“Mandy Red”为例:

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: FlexThemeData.light(scheme: FlexScheme.mandyRed),
      darkTheme: FlexThemeData.dark(scheme: FlexScheme.mandyRed),
      themeMode: ThemeMode.system,
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

自定义颜色方案

你可以定义自己的颜色方案并应用到应用中。以下是一个完整的示例代码,展示了如何自定义颜色和其他主题属性:

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ThemeMode themeMode = ThemeMode.system;
  bool useMaterial3 = true;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Hot Reload Playground',
      theme: FlexThemeData.light(
        useMaterial3: useMaterial3,
        colors: FlexSchemeColor.from(
          primary: const Color(0xFF00296B),
          secondary: const Color(0xFFFF7B00),
          brightness: Brightness.light,
        ),
        appBarStyle: null,
        appBarElevation: 0.5,
        appBarOpacity: 0.94,
        transparentStatusBar: true,
        tabBarStyle: FlexTabBarStyle.forAppBar,
        surfaceMode: FlexSurfaceMode.highBackgroundLowScaffold,
        blendLevel: 8,
        tooltipsMatchBackground: true,
        fontFamily: GoogleFonts.notoSans().fontFamily,
        textTheme: TextTheme(
          displayMedium: TextStyle(fontSize: 41),
          displaySmall: TextStyle(fontSize: 36),
          labelSmall: TextStyle(fontSize: 11, letterSpacing: 0.5),
        ),
        subThemesData: FlexSubThemesData(
          interactionEffects: true,
          defaultRadius: null,
          bottomSheetRadius: 24,
          useMaterial3Typography: true,
          inputDecoratorBorderType: FlexInputBorderType.outline,
          inputDecoratorIsFilled: true,
          inputDecoratorUnfocusedHasBorder: false,
          inputDecoratorSchemeColor: SchemeColor.primary,
          inputDecoratorBackgroundAlpha: 20,
        ),
        visualDensity: FlexColorScheme.comfortablePlatformDensity,
        platform: defaultTargetPlatform,
        extensions: <ThemeExtension<dynamic>>{
          BrandTheme(
            brandColor: Color.fromARGB(255, 8, 79, 71),
          ),
        },
      ),
      darkTheme: FlexThemeData.dark(
        useMaterial3: useMaterial3,
        colors: FlexSchemeColor.from(
          primary: const Color(0xFF6B8BC3),
          secondary: const Color(0xffff7155),
          brightness: Brightness.dark,
        ),
        appBarStyle: null,
        appBarElevation: 0.5,
        appBarOpacity: 0.94,
        transparentStatusBar: true,
        tabBarStyle: FlexTabBarStyle.forAppBar,
        surfaceMode: FlexSurfaceMode.highBackgroundLowScaffold,
        blendLevel: 8,
        tooltipsMatchBackground: true,
        fontFamily: GoogleFonts.notoSans().fontFamily,
        textTheme: TextTheme(
          displayMedium: TextStyle(fontSize: 41),
          displaySmall: TextStyle(fontSize: 36),
          labelSmall: TextStyle(fontSize: 11, letterSpacing: 0.5),
        ),
        subThemesData: FlexSubThemesData(
          interactionEffects: true,
          defaultRadius: null,
          bottomSheetRadius: 24,
          useMaterial3Typography: true,
          inputDecoratorBorderType: FlexInputBorderType.outline,
          inputDecoratorIsFilled: true,
          inputDecoratorUnfocusedHasBorder: false,
          inputDecoratorSchemeColor: SchemeColor.primary,
          inputDecoratorBackgroundAlpha: 20,
        ),
        visualDensity: FlexColorScheme.comfortablePlatformDensity,
        platform: defaultTargetPlatform,
        extensions: <ThemeExtension<dynamic>>{
          BrandTheme(
            brandColor: Color.fromARGB(255, 167, 227, 218),
          ),
        },
      ),
      themeMode: themeMode,
      home: HomePage(
        themeMode: themeMode,
        onThemeModeChanged: (ThemeMode mode) {
          setState(() {
            themeMode = mode;
          });
        },
        useMaterial3: useMaterial3,
        onMaterial3Changed: (bool value) {
          setState(() {
            useMaterial3 = value;
          });
        },
      ),
    );
  }
}

class BrandTheme extends ThemeExtension<BrandTheme> {
  const BrandTheme({
    this.brandColor,
  });

  final Color? brandColor;

  @override
  BrandTheme copyWith({
    Color? brandColor,
  }) =>
      BrandTheme(
        brandColor: brandColor ?? this.brandColor,
      );

  @override
  BrandTheme lerp(ThemeExtension<BrandTheme>? other, double t) {
    if (other is! BrandTheme) {
      return this;
    }
    return BrandTheme(
      brandColor: Color.lerp(brandColor, other.brandColor, t),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({
    required this.themeMode,
    required this.onThemeModeChanged,
    required this.useMaterial3,
    required this.onMaterial3Changed,
  });

  final ThemeMode themeMode;
  final ValueChanged<ThemeMode> onThemeModeChanged;
  final bool useMaterial3;
  final ValueChanged<bool> onMaterial3Changed;

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

class _HomePageState extends State<HomePage> {
  late final ScrollController scrollController;

  @override
  void initState() {
    super.initState();
    scrollController =
        ScrollController(keepScrollOffset: true, initialScrollOffset: 0);
  }

  @override
  void dispose() {
    scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Theme Extension Colored Header'),
            SwitchListTile(
              title: Text('Use Material 3'),
              value: widget.useMaterial3,
              onChanged: (bool value) {
                widget.onMaterial3Changed(value);
              },
            ),
            ListTile(
              title: Text('Theme mode'),
              subtitle: Text('Theme ${widget.themeMode.toString().split('.').last}'),
              trailing: ThemeModeSwitch(
                themeMode: widget.themeMode,
                onChanged: widget.onThemeModeChanged,
              ),
              onTap: () {
                if (Theme.of(context).brightness == Brightness.dark) {
                  widget.onThemeModeChanged(ThemeMode.light);
                } else {
                  widget.onThemeModeChanged(ThemeMode.dark);
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

文档和更多资源

希望这个详细的指南能帮助你更好地理解和使用 flex_color_scheme 插件。如果你有任何问题或需要进一步的帮助,请随时提问!


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

1 回复

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


当然,以下是如何在Flutter项目中使用flex_color_scheme插件来管理色彩方案的示例代码。flex_color_scheme是一个强大的插件,它允许你根据主题(light、dark)和模式(primary、secondary等)灵活地管理应用的色彩方案。

首先,你需要在pubspec.yaml文件中添加flex_color_scheme依赖:

dependencies:
  flutter:
    sdk: flutter
  flex_color_scheme: ^x.y.z  # 替换为最新版本号

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

接下来,在你的Flutter应用中,你可以使用FlexColorSchemeFlexThemeData来设置和应用色彩方案。以下是一个简单的示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlexColorScheme Demo',
      theme: FlexThemeData.light(
        // 设置基础色彩
        colors: FlexColorScheme.tonalPalette(
          baseColor: Color(0xFF6200EA), // 示例基础颜色
          dark: false,
        ).toThemeColors(),
        // 设置文本主题
        textTheme: FlexTextTheme.of(context)
          .copyWith(
            bodyText1: TextStyle(fontSize: 18),
            bodyText2: TextStyle(fontSize: 16),
          ),
      ).toTheme(),
      darkTheme: FlexThemeData.dark(
        // 设置基础色彩
        colors: FlexColorScheme.tonalPalette(
          baseColor: Color(0xFFBB86FC), // 示例基础颜色(深色模式)
          dark: true,
        ).toThemeColors(),
        // 设置文本主题
        textTheme: FlexTextTheme.of(context)
          .copyWith(
            bodyText1: TextStyle(fontSize: 18),
            bodyText2: TextStyle(fontSize: 16),
          ),
      ).toTheme(),
      // 设置主题模式(系统默认、亮色或暗色)
      themeMode: ThemeMode.system,
      // 使用Builder包裹MaterialApp以提供BuilderContext
      builder: (context, child) => Builder(
        builder: (context) {
          // 在这里你可以使用FlexThemeData.of(context)访问当前主题
          return child;
        },
        child: child,
      ),
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 你可以使用FlexThemeData.of(context)来访问当前主题
    final theme = FlexThemeData.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('FlexColorScheme Demo'),
        theme: theme.appBarTheme,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Hello, Flutter!',
              style: theme.textTheme.headline4,
            ),
            ElevatedButton(
              onPressed: () {
                // 切换主题模式
                ThemeMode currentMode = ThemeMode.of(context);
                ThemeMode newMode =
                    currentMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
                MaterialApp.routerDelegate
                    .setNewRoutePath(MaterialApp.routerDelegate.currentConfiguration!.path);
                // 更新主题模式
                ThemeModeSystem.of(context).setThemeMode(newMode);
              },
              child: Text('Toggle Theme Mode'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. pubspec.yaml文件中添加了flex_color_scheme依赖。
  2. 使用FlexThemeData.lightFlexThemeData.dark创建了亮色和暗色主题。
  3. 使用FlexColorScheme.tonalPalette设置了基础色彩。
  4. 设置了文本主题。
  5. MaterialApp中设置了themedarkTheme
  6. 使用ThemeMode.system让应用根据系统主题模式自动切换。
  7. HomeScreen中,通过FlexThemeData.of(context)访问当前主题,并在按钮点击事件中切换主题模式。

这个示例展示了如何使用flex_color_scheme插件来灵活地管理Flutter应用的色彩方案。你可以根据需要进一步自定义和扩展这个示例。

回到顶部