Flutter主题扩展构建插件theme_extensions_builder的使用

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

Flutter主题扩展构建插件theme_extensions_builder的使用

theme_extensions_builder 是一个用于生成Flutter ThemeExtension 类的代码生成器,它可以帮助开发者减少编写样板代码的需求。以下是详细的使用指南,包括安装、配置和创建自定义主题扩展。

安装

要使用 theme_extensions_builder,请确保在项目中添加以下依赖项:

  • build_runner:用于运行代码生成器(开发依赖)
  • theme_extensions_builder:此包(开发依赖)
  • theme_extensions_builder_annotation:为 theme_extensions_builder 提供注解
flutter pub add --dev build_runner
flutter pub add --dev theme_extensions_builder
flutter pub add theme_extensions_builder_annotation

添加导入和部分指令

theme_extensions_builder 是一个基于注解的代码生成器,它会在指定的部分文件中生成代码。请确保在使用注解的文件中添加以下导入和部分指令,并将 "name" 替换为实际文件名。

// file: name.dart

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

part 'name.g.theme.dart';

运行代码生成器

要运行代码生成器,请执行以下命令:

flutter pub run build_runner build --delete-conflicting-outputs

创建主题扩展

下面是一个创建 ElevatedButtonThemeExtension 的示例,展示了如何使用 theme_extensions_builder 来定义和生成主题扩展类。

示例代码

文件:elevated_button.dart

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

part 'elevated_button.g.theme.dart';

@themeExtensions
class ElevatedButtonThemeExtension extends ThemeExtension<ElevatedButtonThemeExtension> with _$ThemeExtensionMixin {
  const ElevatedButtonThemeExtension({
    required this.backgroundColor,
    required this.foregroundColor,
    this.borderRadius,
  });

  final BorderRadius? borderRadius;
  final Color backgroundColor;
  final Color foregroundColor;
}

生成的代码(elevated_button.g.theme.dart)

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'elevated_button.dart';

mixin _$ThemeExtensionMixin on ThemeExtension<ElevatedButtonThemeExtension> {
  @override
  ThemeExtension<ElevatedButtonThemeExtension> copyWith({
    BorderRadius? borderRadius,
    Color? backgroundColor,
    Color? foregroundColor,
  }) {
    final object = this as ElevatedButtonThemeExtension;

    return ElevatedButtonThemeExtension(
      borderRadius: borderRadius ?? object.borderRadius,
      backgroundColor: backgroundColor ?? object.backgroundColor,
      foregroundColor: foregroundColor ?? object.foregroundColor,
    );
  }

  @override
  ThemeExtension<ElevatedButtonThemeExtension> lerp(
    ThemeExtension<ElevatedButtonThemeExtension>? other,
    double t,
  ) {
    final otherValue = other;

    if (otherValue is! ElevatedButtonThemeExtension) {
      return this;
    }

    final value = this as ElevatedButtonThemeExtension;

    return ElevatedButtonThemeExtension(
      borderRadius: BorderRadius.lerp(
        value.borderRadius,
        otherValue.borderRadius,
        t,
      ),
      backgroundColor: Color.lerp(
        value.backgroundColor,
        otherValue.backgroundColor,
        t,
      )!,
      foregroundColor: Color.lerp(
        value.foregroundColor,
        otherValue.foregroundColor,
        t,
      )!,
    );
  }

  @override
  bool operator ==(Object other) {
    final value = this as ElevatedButtonThemeExtension;

    return identical(this, other) ||
        (other.runtimeType == runtimeType &&
            other is ElevatedButtonThemeExtension &&
            identical(value.borderRadius, other.borderRadius) &&
            identical(value.backgroundColor, other.backgroundColor) &&
            identical(value.foregroundColor, other.foregroundColor));
  }

  @override
  int get hashCode {
    final value = this as ElevatedButtonThemeExtension;

    return Object.hash(
      runtimeType,
      value.borderRadius,
      value.backgroundColor,
      value.foregroundColor,
    );
  }
}

extension ElevatedButtonThemeExtensionBuildContext on BuildContext {
  ElevatedButtonThemeExtension get elevatedButtonTheme =>
      Theme.of(this).extension<ElevatedButtonThemeExtension>()!;
}

在VSCode中控制文件嵌套

为了在VSCode的资源管理器中正确嵌套生成的文件,可以在 settings.json 中添加以下配置:

"explorer.fileNesting.patterns": {
    "*.dart": "${capture}.g.theme.dart"
}

完整示例Demo

以下是一个完整的示例,展示了如何在应用中使用自定义的主题扩展。

文件:main.dart

import 'package:flutter/material.dart';
import 'theme/elevated_button.dart';
import 'theme/background.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          extensions: [
            ElevatedButtonThemeExtension(
              foregroundColor: Colors.white,
              backgroundColor: Colors.red,
              borderRadius: BorderRadius.circular(8),
            ),
            const BackgroundThemeExtension(
              color: Colors.grey,
              radius: 6,
            ),
          ],
        ),
        home: const MyHomePage(title: 'Flutter Demo Home Page'),
      );
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({required this.title, super.key});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        backgroundColor: context.backgroundTheme.color,
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
              ElevatedButton(
                onPressed: _incrementCounter,
                child: const Text('Increment'),
              ),
            ],
          ),
        ),
      );
}

文件:theme/elevated_button.dart

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

part 'elevated_button.g.theme.dart';

@themeExtensions
class ElevatedButtonThemeExtension extends ThemeExtension<ElevatedButtonThemeExtension> with _$ThemeExtensionMixin {
  const ElevatedButtonThemeExtension({
    required this.backgroundColor,
    required this.foregroundColor,
    this.borderRadius,
  });

  final BorderRadius? borderRadius;
  final Color backgroundColor;
  final Color foregroundColor;
}

文件:theme/background.dart

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

part 'background.g.theme.dart';

@themeExtensions
class BackgroundThemeExtension extends ThemeExtension<BackgroundThemeExtension> with _$ThemeExtensionMixin {
  const BackgroundThemeExtension({
    required this.color,
    required this.radius,
  });

  final Color color;
  final double radius;
}

通过以上步骤,您可以轻松地使用 theme_extensions_builder 插件来创建和管理自定义的主题扩展,从而简化Flutter应用的主题定制工作。


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

1 回复

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


当然,以下是一个关于如何使用Flutter插件theme_extensions_builder的代码案例。这个插件通常用于扩展和动态构建Flutter应用的主题。以下示例展示了如何集成和使用这个插件。

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

dependencies:
  flutter:
    sdk: flutter
  theme_extensions_builder: ^最新版本号  # 替换为最新版本号

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

示例代码

  1. 创建一个自定义主题扩展类

    你可以创建一个自定义主题扩展类,用于存储你希望在应用中使用的额外主题数据。例如:

    import 'package:flutter/material.dart';
    
    class MyThemeExtensions {
      final Color customBackgroundColor;
      final TextStyle customTextStyle;
    
      MyThemeExtensions({
        required this.customBackgroundColor,
        required this.customTextStyle,
      });
    }
    
  2. 扩展ThemeData

    你需要扩展ThemeData类,以包含自定义主题数据。可以通过创建一个新的类来实现:

    import 'package:flutter/material.dart';
    import 'my_theme_extensions.dart'; // 假设自定义主题扩展类在这个文件中
    
    class MyThemeData extends ThemeData {
      final MyThemeExtensions themeExtensions;
    
      MyThemeData({
        required super.brightness,
        required super.primarySwatch,
        // ... 其他ThemeData参数
        required this.themeExtensions,
      }) : super(
            // 初始化其他ThemeData参数
            brightness: brightness,
            primarySwatch: primarySwatch,
            // ...
          );
    
      // 可以添加一些便捷方法来访问主题扩展属性
      Color get customBackgroundColor => themeExtensions!.customBackgroundColor;
      TextStyle get customTextStyle => themeExtensions!.customTextStyle;
    
      // 静态方法,用于从MaterialApp的theme属性中提取MyThemeData
      static MyThemeData of(BuildContext context) {
        final ThemeData themeData = Theme.of(context);
        return themeData as MyThemeData;
      }
    }
    
  3. 使用ThemeExtensionsBuilder

    现在,你可以使用ThemeExtensionsBuilder来构建使用自定义主题扩展的组件。以下是一个示例:

    import 'package:flutter/material.dart';
    import 'package:theme_extensions_builder/theme_extensions_builder.dart';
    import 'my_theme_data.dart'; // 假设扩展的ThemeData类在这个文件中
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Theme Extensions Demo',
          theme: MyThemeData(
            brightness: Brightness.light,
            primarySwatch: Colors.blue,
            themeExtensions: MyThemeExtensions(
              customBackgroundColor: Colors.amber,
              customTextStyle: TextStyle(color: Colors.white, fontSize: 20),
            ),
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Theme Extensions Demo'),
          ),
          body: ThemeExtensionsBuilder<MyThemeData>(
            builder: (context, theme) {
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(
                      color: theme.customBackgroundColor,
                      child: Text(
                        'Custom Background',
                        style: theme.customTextStyle,
                      ),
                    ),
                  ],
                ),
              );
            },
          ),
        );
      }
    }
    

在这个示例中,我们创建了一个自定义的MyThemeData类,它扩展了ThemeData并包含了一个MyThemeExtensions对象。然后,我们使用ThemeExtensionsBuilder来访问这些自定义主题属性,并在UI组件中使用它们。

注意:theme_extensions_builder插件的具体用法和API可能会根据版本有所不同,请参考官方文档和最新版本以获取最准确的信息。上述代码仅为示例,可能需要根据实际情况进行调整。

回到顶部