flutter如何实现主题切换

在Flutter中如何实现动态主题切换功能?我想让用户可以在应用内自由切换浅色/深色主题,或者自定义主题颜色。目前使用的是MaterialApp的theme属性,但不知道如何实现运行时动态切换,以及如何保存用户选择的主题偏好。有没有完整的实现方案或最佳实践可以参考?

2 回复

Flutter中可使用ThemeThemeData实现主题切换。通过ChangeNotifierProvider管理主题状态,动态切换亮色/暗色主题。

更多关于flutter如何实现主题切换的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现主题切换主要有两种方式:Provider状态管理内置Theme切换。以下是详细实现方法:


1. 使用Provider状态管理(推荐)

步骤:

  1. 添加依赖
dependencies:
  provider: ^6.0.5
  1. 创建主题管理类
import 'package:flutter/material.dart';

class ThemeProvider with ChangeNotifier {
  ThemeMode _themeMode = ThemeMode.light;

  ThemeMode get themeMode => _themeMode;

  void toggleTheme(bool isDark) {
    _themeMode = isDark ? ThemeMode.dark : ThemeMode.light;
    notifyListeners();
  }
}
  1. 在main.dart中配置
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => ThemeProvider(),
      child: const MyApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return Consumer<ThemeProvider>(
      builder: (context, themeProvider, child) {
        return MaterialApp(
          theme: ThemeData.light(),
          darkTheme: ThemeData.dark(),
          themeMode: themeProvider.themeMode,
          home: const HomePage(),
        );
      },
    );
  }
}
  1. 切换主题的UI控件
Switch(
  value: Provider.of<ThemeProvider>(context).themeMode == ThemeMode.dark,
  onChanged: (value) {
    Provider.of<ThemeProvider>(context, listen: false).toggleTheme(value);
  },
)

2. 使用内置方法(简单场景)

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isDark = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: _isDark ? ThemeData.dark() : ThemeData.light(),
      home: Scaffold(
        body: Center(
          child: Switch(
            value: _isDark,
            onChanged: (value) => setState(() => _isDark = value),
          ),
        ),
      ),
    );
  }
}

自定义主题配置

ThemeData(
  primaryColor: Colors.blue,
  accentColor: Colors.orange,
  fontFamily: 'Roboto',
  textTheme: TextTheme(
    headline1: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
  ),
)

总结:

  • 简单应用可用setState直接切换
  • 中大型项目推荐使用Provider等状态管理
  • 可通过ThemeData完全自定义亮色/暗色主题样式
  • 系统级暗色模式支持可通过themeMode: ThemeMode.system实现

实际开发中建议将主题配置抽离为常量,便于统一维护。

回到顶部