Flutter主题创建与管理插件create_theme的使用

Flutter主题创建与管理插件create_theme的使用

create_theme 是一个用于生成 Flutter ThemeExtension 的工具,可以帮助开发者更方便地管理和扩展主题。通过该插件,你可以轻松定义主题属性并自动生成相关代码。

安装

在项目中添加以下依赖:

flutter pub add create_theme_annotation
flutter pub add --dev create_theme

示例代码

my_widget.dart

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

part 'my_widget.g.dart'; // 自动生成的文件

// 默认主题数据生成函数
MyWidgetThemeData _createDefault(ThemeData theme) {
  return MyWidgetThemeData(
    headerColor: theme.colorScheme.primary, // 使用系统主题的颜色方案
    headerTextStyle: TextStyle(
      color: theme.colorScheme.onPrimary, // 设置文本颜色
    ),
    backgroundColor: theme.scaffoldBackgroundColor, // 背景颜色
  );
}

// 使用 @CreateTheme 注解定义主题
@CreateTheme(
  themeProperties: {
    'headerColor': CreateThemeColor(), // 定义颜色属性
    'headerTextStyle': CreateThemeTextStyle(), // 定义文本样式属性
    'backgroundColor': CreateThemeColor(), // 定义背景颜色属性
  },
  createDefault: _createDefault, // 提供默认主题生成逻辑
)
class MyWidget extends StatelessWidget {
  const MyWidget({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    final theme = MyWidgetTheme.of(context); // 获取主题数据

    return Column(
      children: [
        Material(
          color: theme.headerColor, // 使用主题的 headerColor
          child: DefaultTextStyle.merge(
            style: theme.headerTextStyle, // 使用主题的 headerTextStyle
            child: const Padding(
              padding: EdgeInsets.all(8.0),
              child: Center(
                child: Text('Header'), // 显示标题
              ),
            ),
          ),
        ),
        Expanded(
          child: Material(
            color: theme.backgroundColor, // 使用主题的 backgroundColor
            child: const Padding(
              padding: EdgeInsets.all(8.0),
              child: Center(
                child: Text('Body'), // 显示正文
              ),
            ),
          ),
        ),
      ],
    );
  }
}

// 自定义颜色属性类
class CreateThemeColor extends CreateThemeProperties<Color> {
  const CreateThemeColor() : super(propertiesType: Color, lerp: Color.lerp);
}

// 自定义文本样式属性类
class CreateThemeTextStyle extends CreateThemeProperties<TextStyle> {
  const CreateThemeTextStyle()
      : super(propertiesType: TextStyle, lerp: TextStyle.lerp);
}

自动生成的 my_widget.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'my_widget.dart';

// 主题数据类
class MyWidgetThemeData extends ThemeExtension<MyWidgetThemeData> {
  const MyWidgetThemeData({
    this.headerColor,
    this.headerTextStyle,
    this.backgroundColor,
  });

  final Color? headerColor;
  final TextStyle? headerTextStyle;
  final Color? backgroundColor;

  // 复制主题数据
  [@override](/user/override)
  MyWidgetThemeData copyWith({
    Color? headerColor,
    TextStyle? headerTextStyle,
    Color? backgroundColor,
  }) {
    return MyWidgetThemeData(
      headerColor: headerColor ?? this.headerColor,
      headerTextStyle: headerTextStyle ?? this.headerTextStyle,
      backgroundColor: backgroundColor ?? this.backgroundColor,
    );
  }

  // 插值主题数据
  [@override](/user/override)
  MyWidgetThemeData lerp(
    ThemeExtension<MyWidgetThemeData>? other,
    double t,
  ) {
    if (other is! MyWidgetThemeData) return this;

    return MyWidgetThemeData(
      headerColor: Color.lerp(headerColor, other.headerColor, t),
      headerTextStyle:
          TextStyle.lerp(headerTextStyle, other.headerTextStyle, t),
      backgroundColor: Color.lerp(backgroundColor, other.backgroundColor, t),
    );
  }

  // 合并主题数据
  MyWidgetThemeData merge(MyWidgetThemeData? other) {
    if (other == null) return this;

    return copyWith(
      headerColor: other.headerColor,
      headerTextStyle: other.headerTextStyle,
      backgroundColor: other.backgroundColor,
    );
  }

  [@override](/user/override)
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is MyWidgetThemeData &&
        other.headerColor == headerColor &&
        other.headerTextStyle == headerTextStyle &&
        other.backgroundColor == backgroundColor;
  }

  [@override](/user/override)
  int get hashCode {
    return Object.hashAll([
      headerColor,
      headerTextStyle,
      backgroundColor,
    ]);
  }
}

// 主题上下文提供器
class MyWidgetTheme extends InheritedWidget {
  const MyWidgetTheme({
    super.key,
    required this.theme,
    required super.child,
  });

  final MyWidgetThemeData theme;

  [@override](/user/override)
  bool updateShouldNotify(MyWidgetTheme oldWidget) {
    return oldWidget.theme != theme;
  }

  // 获取主题数据
  static MyWidgetThemeData of(BuildContext context) {
    final widget = context.dependOnInheritedWidgetOfExactType<MyWidgetTheme>();
    final localTheme = widget?.theme;

    final theme = Theme.of(context);
    final rootTheme = theme.extensions[MyWidgetThemeData] as MyWidgetThemeData?;

    final MyWidgetThemeData defaultTheme = _createDefault(theme);
    final result = defaultTheme.merge(rootTheme?.merge(localTheme));

    return result;
  }
}

运行示例

以下是完整的运行示例代码:

import 'package:example/src/my_widget.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  runApp(const App());
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      themeMode: ThemeMode.system, // 系统主题模式
      home: Home(),
    );
  }
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Create Theme demo'), // 应用标题
      ),
      body: const SafeArea(
        child: MyWidget(), // 使用自定义组件
      ),
    );
  }
}

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

1 回复

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


create_theme 是一个用于 Flutter 的主题创建与管理的插件,它可以帮助开发者更轻松地定义和管理应用的主题。通过 create_theme,你可以创建自定义的主题,并在应用的不同部分中使用这些主题。

安装

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

dependencies:
  flutter:
    sdk: flutter
  create_theme: ^1.0.0  # 请确保使用最新版本

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

基本用法

  1. 创建主题

    使用 create_theme 插件,你可以定义一个自定义主题。例如:

    import 'package:create_theme/create_theme.dart';
    
    final myTheme = CreateTheme(
      primaryColor: Colors.blue,
      accentColor: Colors.orange,
      textTheme: TextTheme(
        headline1: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
        bodyText1: TextStyle(fontSize: 16, color: Colors.black),
      ),
    );
    
  2. 应用主题

    在你的 MaterialApp 中应用这个主题:

    import 'package:flutter/material.dart';
    import 'package:create_theme/create_theme.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: myTheme.toMaterialTheme(),  // 将自定义主题转换为 MaterialTheme
          home: MyHomePage(),
        );
      }
    }
    
  3. 使用主题

    在你的 Widget 中使用定义的主题:

    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final theme = CreateTheme.of(context);  // 获取当前主题
    
        return Scaffold(
          appBar: AppBar(
            title: Text('My App'),
            backgroundColor: theme.primaryColor,
          ),
          body: Center(
            child: Text(
              'Hello, World!',
              style: theme.textTheme.headline1,
            ),
          ),
        );
      }
    }
    

高级用法

  1. 动态切换主题

    你可以使用 CreateTheme 来动态切换主题。例如,通过 ChangeNotifierProvider 来管理主题状态:

    import 'package:flutter/material.dart';
    import 'package:create_theme/create_theme.dart';
    import 'package:provider/provider.dart';
    
    void main() {
      runApp(
        ChangeNotifierProvider(
          create: (_) => ThemeNotifier(),
          child: MyApp(),
        ),
      );
    }
    
    class ThemeNotifier with ChangeNotifier {
      CreateTheme _currentTheme = myTheme;
    
      CreateTheme get currentTheme => _currentTheme;
    
      void toggleTheme() {
        _currentTheme = _currentTheme == myTheme ? myOtherTheme : myTheme;
        notifyListeners();
      }
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final themeNotifier = Provider.of<ThemeNotifier>(context);
    
        return MaterialApp(
          title: 'Flutter Demo',
          theme: themeNotifier.currentTheme.toMaterialTheme(),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final themeNotifier = Provider.of<ThemeNotifier>(context);
    
        return Scaffold(
          appBar: AppBar(
            title: Text('My App'),
          ),
          body: Center(
            child: ElevatedButton(
              onPressed: () => themeNotifier.toggleTheme(),
              child: Text('Toggle Theme'),
            ),
          ),
        );
      }
    }
    
  2. 扩展主题

    你可以扩展 CreateTheme 来添加更多的自定义属性:

    class MyCustomTheme extends CreateTheme {
      final Color customColor;
    
      MyCustomTheme({
        required this.customColor,
        required Color primaryColor,
        required Color accentColor,
        required TextTheme textTheme,
      }) : super(
            primaryColor: primaryColor,
            accentColor: accentColor,
            textTheme: textTheme,
          );
    }
    
    final myCustomTheme = MyCustomTheme(
      customColor: Colors.purple,
      primaryColor: Colors.blue,
      accentColor: Colors.orange,
      textTheme: TextTheme(
        headline1: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
        bodyText1: TextStyle(fontSize: 16, color: Colors.black),
      ),
    );
回到顶部