Flutter主题管理插件theme_x的使用

Flutter主题管理插件ThemeX的使用

ThemeX是什么?

ThemeX是一个基于Material Design的主题管理插件。你只需要提供主色调,ThemeX会自动生成所有相关的颜色组合调色板。

ThemeX的结果

使用方法

ThemeX的使用非常简单,只需提供主色调,其余部分由ThemeX完成。

创建一个ThemeX实例

final theme = ThemeX(
    brightness: Brightness.light,
    primaryColor: const Color(0xFF684437),
    colorEngine: ThemeXColorEngine.traditional,
);

在MaterialApp中设置主题

MaterialApp(
  title: 'ThemeX',
  theme: theme.get(), // 设置主题属性为ThemeX生成的主题
  home: const MyHomePage(),
);

如何查看视觉结果?

要查看生成的颜色调色板,可以在任何页面或菜单中调用一个对话框:

showDialog(
  context: context,
  builder: (context) {
    return const ThemeXDialog();
  },
);

如何获取ThemeX中的属性?

颜色

获取主色调

var primary = ThemeX.I.primary;

或者获取主色调的不同变体

var primary50 = ThemeX.I.primary[50];
var primary100 = ThemeX.I.primary[100];
var primary200 = ThemeX.I.primary[200];
var primary300 = ThemeX.I.primary[300];
var primary400 = ThemeX.I.primary[400];
var primary500 = ThemeX.I.primary[500];
var primary600 = ThemeX.I.primary[600];
var primary700 = ThemeX.I.primary[700];
var primary800 = ThemeX.I.primary[800];
var primary900 = ThemeX.I.primary[900];

获取次色调

var secondary = ThemeX.I.secondary;

或者获取次色调的不同变体

var secondary100 = ThemeX.I.secondary[100];
var secondary200 = ThemeX.I.secondary[200];
var secondary400 = ThemeX.I.secondary[400];
var secondary700 = ThemeX.I.secondary[700];

获取灰度颜色

var grey = ThemeX.I.grey;

或者获取灰度颜色的不同变体

var grey50 = ThemeX.I.grey[50];
var grey100 = ThemeX.I.grey[100];
var grey200 = ThemeX.I.grey[200];
var grey300 = ThemeX.I.grey[300];
var grey400 = ThemeX.I.grey[400];
var grey500 = ThemeX.I.grey[500];
var grey600 = ThemeX.I.grey[600];
var grey700 = ThemeX.I.grey[700];
var grey800 = ThemeX.I.grey[800];
var grey900 = ThemeX.I.grey[900];

语义颜色

var success = ThemeX.I.success;
var danger = ThemeX.I.danger;
var warning = ThemeX.I.warning;
var info = ThemeX.I.info;
var secondarySuccess = ThemeX.I.secondarySuccess;
var secondaryDanger = ThemeX.I.secondaryDanger;
var secondaryWarning = ThemeX.I.secondaryWarning;
var secondaryInfo = ThemeX.I.secondaryInfo;

字体样式

var h1 = ThemeX.I.h1;
var h2 = ThemeX.I.h2;
var h3 = ThemeX.I.h3;
var h4 = ThemeX.I.h4;
var h5 = ThemeX.I.h5;
var bodyLarge = ThemeX.I.bodyLarge;
var bodyMedium = ThemeX.I.bodyMedium;
var buttonLarge = ThemeX.I.buttonLarge;
var buttonMedium = ThemeX.I.buttonMedium;
var subtitleLarge = ThemeX.I.subtitleLarge;
var subtitleMedium = ThemeX.I.subtitleMedium;

特性

发现高亮/对比色

如果你在一个黄色背景上使用ThemeX,想要找出哪个颜色可以作为高亮色:

var backgroundAccentColor = ThemeX.I.contrastColor(Colors.yellow);

颜色引擎

颜色引擎根据Constantin Material Design、Buckner Material Design和传统Material Design生成颜色变体。

在创建ThemeX时传递颜色引擎属性

final theme = ThemeX(
    brightness: Brightness.light,
    primaryColor: const Color(0xFF684437),
    colorEngine: ThemeXColorEngine.constantin, // 或者ThemeXColorEngine.buckner或ThemeXColorEngine.traditional或ThemeXColorEngine.complementary
);

在创建ThemeX时传递Google字体属性

final theme = ThemeX(
    brightness: Brightness.light,
    primaryColor: const Color(0xFF684437),
    colorEngine: ThemeXColorEngine.constantin, 
    googleFont: GoogleFonts.latoTextTheme, // 传递Google Fonts
);

在创建ThemeX时传递背景颜色属性

final theme = ThemeX(
    brightness: Brightness.light,
    primaryColor: const Color(0xFF684437),
    colorEngine: ThemeXColorEngine.constantin, 
    backgroundColor: (primary, secondary, grey) {
      return Colors.white;
    }, // 传递背景颜色
);

完整示例代码

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

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

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);
  //const Color(0xFFF4D836),  Color(0xFF3f51b5), Color(0xFF684437), Color(0xFF4A59EA)
  final theme = ThemeX(
    brightness: Brightness.light,
    primaryColor: const Color(0xFFE42440),
    backgroundColor: (primary, secondary, grey) {
      return Colors.white;
    },
  );

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: theme.get(),
      home: const MyHomePage(
        title: 'Flutter Demo Home Page',
      ),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final primaryColors = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];
  final greyColors = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];
  final secondaryColors = [100, 200, 400, 700];

  ThemeX get theme => ThemeX.I;

  Widget _buildPrimaryItem(int colorNumber) {
    var hex = theme.toHex8((theme.primary[colorNumber]!));
    return Container(
      color: theme.primary[colorNumber],
      height: 40,
      width: double.infinity,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
              hex.toUpperCase(),
              style: TextStyle(
                  color: theme.contrastColor(theme.primary[colorNumber]!)),
            ),
            Text(
              colorNumber.toString().toUpperCase(),
              style: TextStyle(
                  color: theme.contrastColor(theme.primary[colorNumber]!)),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildSecondaryItem(int colorNumber) {
    var hex = theme.toHex8((theme.secondary[colorNumber]!));
    return Container(
      color: theme.secondary[colorNumber],
      height: 40,
      width: double.infinity,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
              hex.toUpperCase(),
              style: TextStyle(
                  color: theme.contrastColor(theme.secondary[colorNumber]!)),
            ),
            Text(
              colorNumber.toString().toUpperCase(),
              style: TextStyle(
                  color: theme.contrastColor(theme.secondary[colorNumber]!)),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildGreyItem(int colorNumber) {
    var hex = theme.toHex8((theme.grey[colorNumber]!));
    return Container(
      color: theme.grey[colorNumber],
      height: 40,
      width: double.infinity,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
              hex.toUpperCase(),
              style: TextStyle(
                  color: theme.contrastColor(theme.grey[colorNumber]!)),
            ),
            Text(
              colorNumber.toString().toUpperCase(),
              style: TextStyle(
                  color: theme.contrastColor(theme.grey[colorNumber]!)),
            ),
          ],
        ),
      ),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          showDialog(
              context: context,
              builder: (context) {
                return const ThemeXDialog();
              });
        },
        label: const Text("Show ThemeX"),
      ),
      appBar: AppBar(
        elevation: 0,
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ...primaryColors.map((e) => _buildPrimaryItem(e)).toList(),
            ...secondaryColors.map((e) => _buildSecondaryItem(e)).toList(),
            ...greyColors.map((e) => _buildGreyItem(e)).toList(),
            const SizedBox(
              height: 30,
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: SizedBox(
                width: double.infinity,
                child: ElevatedButton.icon(
                  icon: const Icon(Icons.ac_unit),
                  onPressed: () {},
                  label: Text(
                    "Button",
                    style: theme.bodyLarge,
                  ),
                ),
              ),
            ),
            const SizedBox(
              height: 12,
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: SizedBox(
                width: double.infinity,
                child: OutlinedButton.icon(
                  icon: const Icon(Icons.ac_unit),
                  onPressed: () {},
                  label: Text(
                    "Botão",
                    style: theme.bodyLarge,
                  ),
                ),
              ),
            ),
            const SizedBox(
              height: 12,
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextFormField(
                decoration: const InputDecoration(hintText: "Digite um texto"),
              ),
            ),
            const SizedBox(
              height: 12,
            ),
            Text(
              "Headline 1",
              style: theme.h1,
            ),
            Text(
              "Headline 2",
              style: theme.h2,
            ),
            const SizedBox(
              height: 12,
            ),
            Text(
              "Headline 3",
              style: theme.h3,
            ),
            Text(
              "Headline 4",
              style: theme.h4,
            ),
            Text(
              "Headline 5",
              style: theme.h5,
            ),
            const SizedBox(
              height: 8,
            ),
            Text(
              "Subtitle Large",
              style: theme.subtitleLarge,
            ),
            const SizedBox(
              height: 8,
            ),
            Text(
              "Subtitle Medium",
              style: theme.subtitleMedium,
            ),
            const SizedBox(
              height: 8,
            ),
            Text(
              "Body Large",
              style: theme.bodyLarge,
            ),
            const SizedBox(
              height: 8,
            ),
            Text(
              "Body Medium",
              style: theme.bodyMedium,
            ),
            const SizedBox(
              height: 8,
            ),
            Text(
              "Buttom Large",
              style: theme.buttonLarge,
            ),
            const SizedBox(
              height: 8,
            ),
            Text(
              "Buttom Medium",
              style: theme.buttonMedium,
            ),
            const SizedBox(
              height: 8,
            ),
            Text(
              "Caption",
              style: theme.caption,
            ),
            const SizedBox(
              height: 30,
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


theme_x 是一个用于 Flutter 应用的主题管理插件,它可以帮助开发者更方便地管理和切换应用的主题。通过 theme_x,你可以定义多个主题,并在运行时动态切换它们。以下是如何使用 theme_x 插件的基本步骤:

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 theme_x 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  theme_x: ^1.0.0  # 请使用最新版本

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

2. 定义主题

接下来,你可以定义多个主题。通常,你可以将这些主题定义在一个单独的文件中,例如 themes.dart

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

class AppThemes {
  static final ThemeData lightTheme = ThemeData(
    primarySwatch: Colors.blue,
    brightness: Brightness.light,
  );

  static final ThemeData darkTheme = ThemeData(
    primarySwatch: Colors.indigo,
    brightness: Brightness.dark,
  );

  static final ThemeData customTheme = ThemeData(
    primarySwatch: Colors.green,
    accentColor: Colors.orange,
    brightness: Brightness.light,
  );
}

3. 初始化 ThemeX

在你的应用启动时,初始化 ThemeX 并设置默认主题:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ThemeX(
      defaultTheme: AppThemes.lightTheme,
      child: MaterialApp(
        title: 'ThemeX Example',
        theme: ThemeX.of(context), // 使用 ThemeX 提供的主题
        home: HomeScreen(),
      ),
    );
  }
}

4. 切换主题

你可以在应用的任何地方使用 ThemeX 来切换主题。例如,在设置页面中提供一个切换主题的按钮:

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

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ThemeX Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                ThemeX.of(context).setTheme(AppThemes.lightTheme);
              },
              child: Text('Light Theme'),
            ),
            ElevatedButton(
              onPressed: () {
                ThemeX.of(context).setTheme(AppThemes.darkTheme);
              },
              child: Text('Dark Theme'),
            ),
            ElevatedButton(
              onPressed: () {
                ThemeX.of(context).setTheme(AppThemes.customTheme);
              },
              child: Text('Custom Theme'),
            ),
          ],
        ),
      ),
    );
  }
}

5. 获取当前主题

你可以通过 ThemeX.of(context).currentTheme 来获取当前应用的主题:

ThemeData currentTheme = ThemeX.of(context).currentTheme;
回到顶部