在CentOS下实现Flutter主题切换的常见方法
在CentOS系统上进行Flutter开发时,主题切换的核心逻辑与Windows、macOS等平台一致,主要依赖Flutter的ThemeData系统结合状态管理工具(如ValueNotifier、Provider或第三方库adaptive_theme)。以下是具体实现步骤:
在CentOS终端中,使用以下命令创建新的Flutter项目(确保已安装Flutter SDK并配置好环境变量):
flutter create theme_switch_demo
cd theme_switch_demo
适用于小型项目,无需复杂状态管理的场景。
在lib目录下创建theme_controller.dart,定义亮色、暗色主题及状态管理类:
import 'package:flutter/material.dart';
// 定义主题数据
class AppThemes {
static final lightTheme = ThemeData(
brightness: Brightness.light,
primaryColor: Colors.blue,
scaffoldBackgroundColor: Colors.white,
);
static final darkTheme = ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.blueGrey,
scaffoldBackgroundColor: Colors.black,
);
}
// 主题状态管理类
class ThemeController extends ValueNotifier<bool> {
ThemeController() : super(false); // false表示亮色模式
// 切换主题
void changeTheme() {
value = !value;
}
}
修改lib/main.dart,使用ValueListenableBuilder动态更新主题:
import 'package:flutter/material.dart';
import 'theme_controller.dart';
void main() {
runApp(const MyApp());
}
final themeController = ThemeController(); // 全局主题控制器
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<bool>(
valueListenable: themeController,
builder: (context, isDark, child) {
return MaterialApp(
title: 'CentOS Flutter Theme Demo',
theme: AppThemes.lightTheme, // 亮色主题
darkTheme: AppThemes.darkTheme, // 暗色主题
themeMode: isDark ? ThemeMode.dark : ThemeMode.light, // 根据状态切换模式
home: const MyHomePage(),
);
},
);
}
}
修改lib/my_home_page.dart,通过按钮触发主题切换:
import 'package:flutter/material.dart';
import 'theme_controller.dart';
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('主题切换')),
body: Center(
child: ValueListenableBuilder<bool>(
valueListenable: themeController,
builder: (context, isDark, child) {
return Switch(
value: isDark,
onChanged: (value) {
themeController.changeTheme(); // 切换主题状态
},
activeColor: Colors.blue,
inactiveThumbColor: Colors.grey,
);
},
),
),
);
}
}
适用于中大型项目,支持多组件共享主题状态。
修改pubspec.yaml,添加provider依赖:
dependencies:
flutter:
sdk: flutter
provider: ^6.1.1
运行flutter pub get安装依赖。
修改theme_controller.dart,继承ChangeNotifier:
import 'package:flutter/material.dart';
enum ThemeModeEnum { light, dark }
class ThemeProvider with ChangeNotifier {
ThemeModeEnum _themeMode = ThemeModeEnum.light;
ThemeModeEnum get themeMode => _themeMode;
// 切换主题
void toggleTheme(bool isDark) {
_themeMode = isDark ? ThemeModeEnum.dark : ThemeModeEnum.light;
notifyListeners(); // 通知所有监听组件刷新
}
}
修改lib/main.dart,使用ChangeNotifierProvider包裹根组件:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'theme_provider.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => ThemeProvider(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final themeProvider = Provider.of<ThemeProvider>(context);
return MaterialApp(
title: 'CentOS Flutter Theme Demo',
theme: ThemeData.light(), // 亮色主题
darkTheme: ThemeData.dark(), // 暗色主题
themeMode: themeProvider.themeMode == ThemeModeEnum.light
? ThemeMode.light
: ThemeMode.dark, // 根据状态切换模式
home: const MyHomePage(),
);
}
}
修改lib/my_home_page.dart,通过Consumer监听状态变化:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'theme_provider.dart';
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
final themeProvider = Provider.of<ThemeProvider>(context);
return Scaffold(
appBar: AppBar(title: const Text('主题切换')),
body: Center(
child: Consumer<ThemeProvider>(
builder: (context, provider, child) {
return Switch(
value: provider.themeMode == ThemeModeEnum.dark,
onChanged: (value) {
provider.toggleTheme(value); // 切换主题
},
activeColor: Colors.blue,
);
},
),
),
);
}
}
适用于需要保存用户偏好、自定义颜色或支持系统主题的项目。
修改pubspec.yaml,添加adaptive_theme依赖:
dependencies:
flutter:
sdk: flutter
adaptive_theme: ^3.6.0
运行flutter pub get安装依赖。
修改lib/main.dart,使用AdaptiveTheme包裹MaterialApp:
import 'package:flutter/material.dart';
import 'package:adaptive_theme/adaptive_theme.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 读取保存的主题模式(可选)
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return AdaptiveTheme(
// 定义亮色、暗色主题
light: ThemeData.light().copyWith(
primaryColor: Colors.blue,
scaffoldBackgroundColor: Colors.white,
),
dark: ThemeData.dark().copyWith(
primaryColor: Colors.blueGrey,
scaffoldBackgroundColor: Colors.black,
),
initial: AdaptiveThemeMode.light, // 初始模式(light/dark/system)
debugShowFloatingThemeButton: true, // 显示调试按钮(可选)
builder: (lightTheme, darkTheme) {
return MaterialApp(
title: 'CentOS Flutter Theme Demo',
theme: lightTheme, // 亮色主题
darkTheme: darkTheme, // 暗色主题
home: const MyHomePage(),
);
},
);
}
}
修改lib/my_home_page.dart,使用AdaptiveTheme提供的方法切换主题:
import 'package:flutter/material.dart';
import 'package:adaptive_theme/adaptive_theme.dart';
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('主题切换')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).toggleThemeMode(); // 切换亮/暗模式
},
child: const Text('切换主题'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).setLight(); // 强制设置为亮色模式
},
child: const Text('设为亮色'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).setDark(); // 强制设置为暗色模式
},
child: const Text('设为暗色'),
),
],
),
),
);
}
}
flutter doctor检查环境是否正常。ValueNotifier,中大型项目推荐Provider或Riverpod,需要高级功能(如保存用户偏好)推荐adaptive_theme。ThemeData的primaryColor、scaffoldBackgroundColor、textTheme等属性,实现自定义主题样式。shared_preferences库(适用于ValueNotifier/Provider)或adaptive_theme的内置保存功能。以上方法均可在CentOS系统上正常运行,根据项目需求选择合适的方式即可。