颤动中的亮/暗模式
Light / Dark Mode in flutter
我想将 light/dark 模式开关放在应用程序中。开关没问题。但它在应用程序中没有任何变化。只是我看到了浅色主题。
而且,当我单击开关时,出现此错误或警告 (idk)。 :抛出另一个异常:试图从小部件树外部侦听提供者公开的值。
这是main.dart:
import 'package:provider/provider.dart';
import 'package:bankingapp/widget/themestate.dart';
void main() {
runApp(ChangeNotifierProvider<ThemeState>(
create: (context) => ThemeState(),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: Provider.of<ThemeState>(context).theme == ThemeType.DARK
? ThemeData.dark()
: ThemeData.light(),
debugShowCheckedModeBanner: false,
home: MySplash(),
);
}
}
这是homescreen.dart:
Container(
child: Switch(
value: Provider.of<ThemeState>(context).theme == ThemeType.DARK,
onChanged: (value) {
Provider.of<ThemeState>(context).theme =
value ? ThemeType.DARK : ThemeType.LIGHT;
setState(() {});
},
),
),
这是themestate.dart:
import 'package:flutter/material.dart';
enum ThemeType { DARK, LIGHT }
class ThemeState extends ChangeNotifier {
bool _isDarkTheme = false;
ThemeState() {
getTheme().then((type) {
_isDarkTheme = type == ThemeType.DARK;
notifyListeners();
});
}
ThemeType get theme => _isDarkTheme ? ThemeType.DARK : ThemeType.LIGHT;
set theme(ThemeType type) => setTheme(type);
void setTheme(ThemeType type) async {
_isDarkTheme = type == ThemeType.DARK;
notifyListeners();
}
Future<ThemeType> getTheme() async {
return _isDarkTheme ? ThemeType.DARK : ThemeType.LIGHT;
}
}
注意:这段代码是ThemeS项目的一部分。因为代码由很长的一行组成。
在按钮上调用 Provider.of
时,您应该始终传递 listen: false
,如下所示:
onChanged: (value) {
Provider.of<ThemeState>(context, listen: false).theme =
value ? ThemeType.DARK : ThemeType.LIGHT;
setState(() {});
})
老实说,我不确定这是否会修复您的代码,但是当我尝试复制您的错误时,我收到了以下错误消息:
════════ Exception caught by gesture ═══════════════════════════════════════════
Tried to listen to a value exposed with provider, from outside of the widget tree.
This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.
这是我的最小示例,在添加 listen: false
后有效
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(ChangeNotifierProvider<MyValue>(
create: (context) => MyValue(true),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Checkbox(
value: Provider.of<MyValue>(context).value,
onChanged: (val) {
Provider.of<MyValue>(context, listen: false).value = val!;
setState(() {});
},
),
),
);
}
}
class MyValue extends ChangeNotifier {
MyValue(this.value);
bool value;
}
所以我希望添加 listen: false
可以解决您的问题
我想将 light/dark 模式开关放在应用程序中。开关没问题。但它在应用程序中没有任何变化。只是我看到了浅色主题。 而且,当我单击开关时,出现此错误或警告 (idk)。 :抛出另一个异常:试图从小部件树外部侦听提供者公开的值。
这是main.dart:
import 'package:provider/provider.dart';
import 'package:bankingapp/widget/themestate.dart';
void main() {
runApp(ChangeNotifierProvider<ThemeState>(
create: (context) => ThemeState(),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: Provider.of<ThemeState>(context).theme == ThemeType.DARK
? ThemeData.dark()
: ThemeData.light(),
debugShowCheckedModeBanner: false,
home: MySplash(),
);
}
}
这是homescreen.dart:
Container(
child: Switch(
value: Provider.of<ThemeState>(context).theme == ThemeType.DARK,
onChanged: (value) {
Provider.of<ThemeState>(context).theme =
value ? ThemeType.DARK : ThemeType.LIGHT;
setState(() {});
},
),
),
这是themestate.dart:
import 'package:flutter/material.dart';
enum ThemeType { DARK, LIGHT }
class ThemeState extends ChangeNotifier {
bool _isDarkTheme = false;
ThemeState() {
getTheme().then((type) {
_isDarkTheme = type == ThemeType.DARK;
notifyListeners();
});
}
ThemeType get theme => _isDarkTheme ? ThemeType.DARK : ThemeType.LIGHT;
set theme(ThemeType type) => setTheme(type);
void setTheme(ThemeType type) async {
_isDarkTheme = type == ThemeType.DARK;
notifyListeners();
}
Future<ThemeType> getTheme() async {
return _isDarkTheme ? ThemeType.DARK : ThemeType.LIGHT;
}
}
注意:这段代码是ThemeS项目的一部分。因为代码由很长的一行组成。
在按钮上调用 Provider.of
时,您应该始终传递 listen: false
,如下所示:
onChanged: (value) {
Provider.of<ThemeState>(context, listen: false).theme =
value ? ThemeType.DARK : ThemeType.LIGHT;
setState(() {});
})
老实说,我不确定这是否会修复您的代码,但是当我尝试复制您的错误时,我收到了以下错误消息:
════════ Exception caught by gesture ═══════════════════════════════════════════
Tried to listen to a value exposed with provider, from outside of the widget tree.
This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.
这是我的最小示例,在添加 listen: false
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(ChangeNotifierProvider<MyValue>(
create: (context) => MyValue(true),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Checkbox(
value: Provider.of<MyValue>(context).value,
onChanged: (val) {
Provider.of<MyValue>(context, listen: false).value = val!;
setState(() {});
},
),
),
);
}
}
class MyValue extends ChangeNotifier {
MyValue(this.value);
bool value;
}
所以我希望添加 listen: false
可以解决您的问题