[英]How to use a switch to change between light and dark theme with Provider in Flutter?
I'm a flutter beginner and recently I've been trying to figure out how to dynamically switch between dark and light themes using a switch.我是 flutter 初学者,最近我一直在尝试弄清楚如何使用开关在深色和浅色主题之间动态切换。 I've watched several tutorials, then tried to figure it out on my own.
我看了几个教程,然后尝试自己弄清楚。 After a few hours I got to this point, where I'm seeing no errors and where I think the code is doing the right things.
几个小时后,我到了这一点,我没有看到任何错误,并且我认为代码正在做正确的事情。 Essentially the problem is that the switch turns off, but then turns back on, with no change in theme.
本质上问题是开关关闭,然后重新打开,主题没有变化。 I suspect I wrote some wrong code somewhere, but I'm not sure where.
我怀疑我在某处写了一些错误的代码,但我不确定在哪里。 Here is the code:
这是代码:
This is my main.dart file:这是我的 main.dart 文件:
import 'package:provider/provider.dart';
import 'package:working_with_fin_apis/providers/theme_provider.dart';
import 'package:working_with_fin_apis/screens/home_page.dart';
import 'package:working_with_fin_apis/screens/settings_page.dart';
void main() {
runApp(
MultiProvider(providers: [
ChangeNotifierProvider(
create: (_) => ThemeProvider(),
),
], child: const MyApp()),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
themeMode: Provider.of<ThemeProvider>(context).themeMode,
initialRoute: '/',
routes: {
'/': (context) => const HomePage(),
'/settings': (context) => const SettingsPage(),
});
}
}
This is my settings.dart, where the switch is:这是我的设置。dart,其中的开关是:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:working_with_fin_apis/providers/theme_provider.dart';
class SettingsPage extends StatelessWidget {
const SettingsPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'PlaceHolder',
style: TextStyle(),
),
actions: [
IconButton(
onPressed: () {
Navigator.pushNamed(context, '/');
},
icon: const Icon(Icons.arrow_back),
),
],
),
body: Center(
child: Column(
children: [
Switch(
value: true,
onChanged: Provider.of<ThemeProvider>(context).toggleTheme(true),
),
],
),
),
);
}
}
And finally my theme_provider.dart that has the actual ChangeNotifier:最后我的 theme_provider.dart 具有实际的 ChangeNotifier:
import 'package:flutter/material.dart';
class ThemeProvider with ChangeNotifier {
ThemeMode _theme = ThemeMode.light;
ThemeMode get themeMode => _theme;
dynamic toggleTheme(bool isDark) {
_theme = isDark ? ThemeMode.dark : ThemeMode.light;
notifyListeners();
}
}
So my question is what am I missing?所以我的问题是我错过了什么? I think it's just a wrong way of notifying each of the different parts, but I'm not sure.
我认为这只是通知每个不同部分的错误方式,但我不确定。 I'm trying to find the simplest solution but I can't seem to figure it out, most of the code is inspired from provider tutorials that weren't related to theming, so that might be some of the problem.
我试图找到最简单的解决方案,但我似乎无法弄清楚,大部分代码的灵感来自与主题无关的提供者教程,所以这可能是一些问题。 Any advice or resources are welcome, thanks.
欢迎任何建议或资源,谢谢。
You have to declare a bool variable in the provider for the switch to work correctly您必须在提供程序中声明一个 bool 变量才能使开关正常工作
bool _isDark = false;
bool get isDark => _isDark;
And change its value in the function with the new value并将其在 function 中的值更改为新值
void toggleTheme(bool newValue) {
_isDark = newValue;
if (_theme == ThemeMode.lightTheme) {
_theme = ThemeMode.darkTheme;
} else {
_theme = ThemeMode.lightTheme;
}
notifyListeners();
}
And in the switch widget use this bool variable and receive the value in onChanged and pass it to the provider function and set listen to false in the provider call for the function并在开关小部件中使用此 bool 变量并接收 onChanged 中的值并将其传递给提供者 function 并在提供者调用中为 function 设置监听为 false
Switch(
value: Provider.of<ThemeProvider>(context).isDark,
onChanged:(value) => Provider.of<ThemeProvider>(context,listen: false).toggleTheme(value),
),
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.