Flutter自定义主题样式插件custom_theme_style的使用

Flutter 自定义主题样式插件 custom_theme_style 的使用

custom_theme_style 是一个帮助开发者创建自定义主题并覆盖方法的新 Flutter 包。此包允许你定义和使用自定义主题,支持亮色模式和暗色模式,并提供了一种动态定制小部件外观的方法。

特性

  • 定义各种组件的自定义主题
  • 支持亮色和暗色模式
  • 轻松在项目间共享主题
  • 动态自定义小部件外观

开始使用

要使用此插件,请遵循以下步骤:

1. 添加依赖

pubspec.yaml 文件中添加 custom_theme_style 作为依赖项:

dependencies:
  custom_theme_style: ^0.0.1
2. 定义自定义主题
MaterialApp(
  title: 'Flutter Demo',
  theme: CustomThemeData.lightThemeData(
    isTablet: DeviceUtils.isTablet(context),
  ),
  darkTheme: CustomThemeData.darkThemeData(
    isTablet: DeviceUtils.isTablet(context),
  ),
  themeMode: ThemeMode.system,
  home: const MyHomePage(),
);
3. 访问自定义主题

为了方便访问此主题,定义一个静态的 BuildContext 方法:

class CustomThemeData {
  static ThemeData lightThemeData({required bool isTablet}) {
    // 定义亮色主题
  }

  static ThemeData darkThemeData({required bool isTablet}) {
    // 定义暗色主题
  }
}

extension CustomTheme on BuildContext {
  CustomThemeData get customTheme => CustomThemeData.of(this);
}
4. 在小部件中使用自定义主题

现在你可以在小部件中使用自定义主题了:

Text(
  '显示中等文本',
  style: GoogleFonts.robotoSlab(
    fontSize: Theme.of(context).textTheme.displayMedium?.fontSize,
    color: isColor ? Colors.pink : Theme.of(context).textTheme.displayMedium?.color,
  ),
);

应用自定义样式

如果需要动态更改主题颜色,可以使用 CustomTextStyle.applyCustomStyle() 方法:

Text(
  '显示小文本',
  style: CustomTextStyle.applyCustomStyle(
    Theme.of(context).textTheme.displaySmall,
    color: isColor ? Colors.purple : Theme.of(context).textTheme.bodySmall?.color,
  ),
);

何时使用

当你在项目之间共享小部件或功能时,可以使用此插件。例如:

1. 可重用的小部件
创建一个像 TextButton 这样的小部件,它在不同的项目中看起来不同

与其在每个项目中创建具有自定义外观的不同小部件,不如定义一个自定义主题并应用它。通过使用 custom_theme,你可以定义自己的主题,并轻松在项目之间共享小部件或功能,确保一致的样式并减少冗余代码。

示例代码

以下是完整的示例代码:

import 'package:custom_theme_style/custom_theme_style.dart';
import 'package:custom_theme_style/resource/device_utils.dart';
import 'package:custom_theme_style/theme/custom_theme_data.dart';
import 'package:flutter/material.dart';

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

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

  // 此小部件是您的应用程序的根。
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '自定义主题演示',
      theme: CustomThemeData.lightThemeData(
        isTablet: DeviceUtils.isTablet(context),
      ),
      darkTheme: CustomThemeData.darkThemeData(
        isTablet: DeviceUtils.isTablet(context),
      ),
      themeMode: ThemeMode.system,
      home: const MyHomePage(),
    );
  }
}

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

  // 此小部件是您的应用程序的主页。它是有状态的,意味着
  // 它有一个包含影响其外观的字段的状态对象(在下面定义)。
  // 此类是状态的配置。它保存由父级(在此情况下为 App 小部件)提供的值(在此情况下为标题),并在构建方法中使用。
  // 小部件子类中的字段始终标记为 "final"。

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

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

  void _incrementCounter() {
    setState(() {
      // 此调用告诉 Flutter 框架某些内容已更改,
      // 导致重新运行下方的构建方法,以便显示更新后的值。
      // 如果我们不调用 setState() 更改 _counter,则不会重新运行构建方法,
      // 因此似乎没有任何事情发生。
      _counter++;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    // 每当调用 setState 时,此方法都会重新运行,例如在上面的 _incrementCounter 方法中。
    //
    // Flutter 框架已针对快速重建构建方法进行了优化,
    // 因此您可以重建任何需要更新的内容,而不是逐个更改小部件实例。
    return Scaffold(
      appBar: AppBar(
        // 尝试:尝试将此处的颜色更改为特定颜色(例如 Colors.amber),然后触发热重载以查看 AppBar 颜色变化,而其他颜色保持不变。
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        // 我们在这里获取由 App.build 方法创建的 MyHomePage 对象的值,
        // 并将其用于设置我们的 appbar 标题。
        title: Text(widget.title, style: Theme.of(context).textTheme.bodyLarge),
      ),
      body: Center(
        // Center 是一个布局小部件。它接受单个子元素并将其中心定位到父元素的中间。
        child: Column(
          // Column 也是一个布局小部件。它接受子元素列表并垂直排列它们。
          // 默认情况下,它水平调整自身大小以适应其子元素,并尽可能高。
          //
          // Column 有几个属性可控制其如何调整自身大小和如何定位其子元素。
          // 在这里,我们使用 mainAxisAlign 来垂直居中子元素;主轴在此处是垂直的(交叉轴将是水平的)。
          //
          // 尝试:启用“调试绘制”(在 IDE 中选择“切换调试绘制”操作,或在控制台中按“p”键),以查看每个小部件的线框图。
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              '您已经按下了按钮这么多次:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.bodyLarge,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: '增加',
        child: const Icon(Icons.add),
      ), // 这个逗号使自动格式化更好看。
    );
  }
}

更多关于Flutter自定义主题样式插件custom_theme_style的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义主题样式插件custom_theme_style的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在 Flutter 中,自定义主题样式是常见的需求,特别是在需要根据应用的不同部分或用户偏好来动态更改主题时。custom_theme_style 是一个可能用于自定义主题样式的插件(假设它是一个社区或第三方插件),虽然截至 2023 年 10 月,Flutter 官方并没有一个名为 custom_theme_style 的标准插件,但你可以使用 Flutter 内置的 ThemeThemeData 来实现类似的功能。

以下是如何使用 Flutter 内置功能来自定义主题样式的方法:


1. 创建自定义主题

使用 ThemeData 定义你的主题样式:

final ThemeData customTheme = ThemeData(
  primaryColor: Colors.blue,
  accentColor: Colors.orange,
  fontFamily: 'Roboto',
  textTheme: TextTheme(
    headline1: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
    bodyText1: TextStyle(fontSize: 16, color: Colors.black87),
  ),
);

2. 应用自定义主题

MaterialApp 中使用 theme 属性应用自定义主题:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Theme Example',
      theme: customTheme, // 应用自定义主题
      home: HomeScreen(),
    );
  }
}

3. 在 Widget 中使用主题

通过 Theme.of(context) 获取当前主题,并在 Widget 中使用:

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Theme Example'),
      ),
      body: Center(
        child: Text(
          'Hello, Custom Theme!',
          style: Theme.of(context).textTheme.headline1, // 使用自定义主题的文本样式
        ),
      ),
    );
  }
}

4. 动态切换主题

如果需要动态切换主题,可以使用 ChangeNotifierProvider 来实现:

class ThemeProvider with ChangeNotifier {
  ThemeData _currentTheme = customTheme;

  ThemeData get currentTheme => _currentTheme;

  void toggleTheme() {
    _currentTheme = _currentTheme == customTheme ? darkTheme : customTheme;
    notifyListeners();
  }
}

final ThemeData darkTheme = ThemeData(
  primaryColor: Colors.black,
  accentColor: Colors.grey,
  fontFamily: 'Roboto',
  textTheme: TextTheme(
    headline1: TextStyle(fontSize: 32, fontWeight: FontWeight.bold, color: Colors.white),
    bodyText1: TextStyle(fontSize: 16, color: Colors.white70),
  ),
);

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => ThemeProvider(),
      child: Consumer<ThemeProvider>(
        builder: (context, themeProvider, child) {
          return MaterialApp(
            title: 'Dynamic Theme Example',
            theme: themeProvider.currentTheme, // 动态主题
            home: HomeScreen(),
          );
        },
      ),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final themeProvider = Provider.of<ThemeProvider>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('Dynamic Theme Example'),
      ),
      body: Center(
        child: Text(
          'Hello, Dynamic Theme!',
          style: Theme.of(context).textTheme.headline1,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          themeProvider.toggleTheme(); // 切换主题
        },
        child: Icon(Icons.color_lens),
      ),
    );
  }
}

5. 使用自定义主题插件(如 custom_theme_style

如果你找到或实现了一个名为 custom_theme_style 的插件,使用方法通常会类似于以下步骤:

  1. pubspec.yaml 中添加依赖:
    dependencies:
      custom_theme_style: ^1.0.0
    
  2. 导入插件:
    import 'package:custom_theme_style/custom_theme_style.dart';
回到顶部