使用 Provider 实现主题切换
- 创建主题数据:
在Flutter中,通过
ThemeData
类定义亮色和暗色主题。
final ThemeData lightTheme = ThemeData(
brightness: Brightness.light,
primaryColor: Colors.blue,
// 其他亮色主题相关样式
);
final ThemeData darkTheme = ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.grey[800],
// 其他暗色主题相关样式
);
- 状态管理:
使用
Provider
包,创建一个主题状态管理类。
class ThemeProvider with ChangeNotifier {
ThemeData _currentTheme = lightTheme;
ThemeData get currentTheme => _currentTheme;
void toggleTheme() {
_currentTheme = _currentTheme == lightTheme? darkTheme : lightTheme;
notifyListeners();
}
}
- 应用主题:
在
MaterialApp
中使用Provider
提供主题数据。
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => ThemeProvider(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final themeProvider = Provider.of<ThemeProvider>(context);
return MaterialApp(
theme: themeProvider.currentTheme,
home: HomePage(),
);
}
}
- 切换主题:
在需要切换主题的地方,如按钮点击事件中,调用
toggleTheme
方法。
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('主题切换示例')),
body: Center(
child: ElevatedButton(
onPressed: () {
final themeProvider = Provider.of<ThemeProvider>(context, listen: false);
themeProvider.toggleTheme();
},
child: Text('切换主题'),
),
),
);
}
}
使用 Bloc 实现主题切换
- 定义主题状态和事件:
// 主题状态
enum ThemeModeState { light, dark }
class ThemeModeBloc extends Bloc<ThemeModeEvent, ThemeModeState> {
ThemeModeBloc() : super(ThemeModeState.light);
@override
Stream<ThemeModeState> mapEventToState(ThemeModeEvent event) async* {
if (event is ToggleThemeModeEvent) {
yield state == ThemeModeState.light? ThemeModeState.dark : ThemeModeState.light;
}
}
}
// 主题事件
abstract class ThemeModeEvent {}
class ToggleThemeModeEvent extends ThemeModeEvent {}
- 应用主题:
在
MaterialApp
中根据Bloc
状态应用主题。
void main() {
runApp(
BlocProvider(
create: (context) => ThemeModeBloc(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final themeModeState = context.watch<ThemeModeBloc>().state;
return MaterialApp(
theme: themeModeState == ThemeModeState.light? lightTheme : darkTheme,
home: HomePage(),
);
}
}
- 切换主题:
在按钮点击事件中添加
ToggleThemeModeEvent
。
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('主题切换示例')),
body: Center(
child: ElevatedButton(
onPressed: () {
context.read<ThemeModeBloc>().add(ToggleThemeModeEvent());
},
child: Text('切换主题'),
),
),
);
}
}
常用组件样式调整
- Button:
- 亮色主题:按钮的
color
可以是primaryColor
,textColor
通常为白色。
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
primary: Theme.of(context).primaryColor,
onPrimary: Colors.white,
),
child: Text('按钮'),
);
- 暗色主题:按钮的
color
可以是primaryColor
,textColor
通常为亮色,如白色或浅灰色。
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
primary: Theme.of(context).primaryColor,
onPrimary: Colors.white,
),
child: Text('按钮'),
);
- Card:
- 亮色主题:
Card
的color
通常为白色,阴影颜色根据主题调整。
Card(
color: Colors.white,
elevation: 4.0,
child: Container(
// 卡片内容
),
);
- 暗色主题:
Card
的color
通常为较深的颜色,如Colors.grey[800]
,阴影颜色也相应调整以适配暗色背景。
Card(
color: Colors.grey[800],
elevation: 4.0,
child: Container(
// 卡片内容
),
);