我有一个MaterialApp
,其中一个ThemeData
最初设置为Brightness.light
。我想在运行时将亮度切换为Brightness.dark
,但是当我进行更改时,只有状态栏会更改-Flutter小部件实际上没有更改其亮度。
如何实现这种行为?
要在运行时更改ThemeData
,我创建了以下StatefulWidget
,该MaterialApp
包装了final ThemeData appTheme = ThemeData(
brightness: Brightness.light,
);
class ThemeChanger extends StatefulWidget {
static ThemeChangerState of (BuildContext context) {
return context.ancestorStateOfType(TypeMatcher<ThemeChangerState>());
}
ThemeChanger({
this.childBuilder,
});
final Widget Function(BuildContext, ThemeData) childBuilder;
@override
ThemeChangerState createState() => ThemeChangerState();
}
class ThemeChangerState extends State<ThemeChanger> {
Brightness _brightness = Brightness.light;
set brightness(Brightness brightness) {
setState(() {
_brightness = brightness;
});
}
@override
Widget build(BuildContext context) {
return widget.childBuilder(
context,
appTheme.copyWith(
brightness: _brightness
),
);
}
}
// Then in main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DemoTheme(
childBuilder: (BuildContext context, ThemeData theme) {
return MaterialApp(
title: 'Materially Better',
theme: theme,
routes: {
'/': (BuildContext context) {
return LoginScreen();
},
'home': (BuildContext context) {
return MainScreen();
}
},
debugShowCheckedModeBanner: false,
);
},
);
}
}
并在主题更改时重新构建它:
ThemeData
答案 0 :(得分:2)
问题是brightness
在构造函数中使用其ThemeData
值来合成许多其他颜色,但是当ThemeData
发生突变时,这些颜色不会重新计算。因此,解决方案是实例化全新的appTheme.copyWith(...)
而不是使用appTheme.copyWith(
brightness: _brightness,
),
。
更改此:
ThemeData(
brightness: _brightness,
),
对此:
#/usr/bin/env sh
echo -e "What VM?"
read vname
if [ '`VboxManage list vms | grep -c "$vname"`' != 0 ]; then
echo exists
fi
答案 1 :(得分:1)
我的解决方法是:
在main.dart
中为亮度定义一个变量,并更改状态的函数。
将函数传递给类,然后在需要的地方调用它。
//main.dart
class _MyAppState extends State<MyApp> {
Brightness _brightness = Brightness.light;
void _changeBrightness(Brightness newBrightness) {
setState(() {
_brightness = newBrightness;
});
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
//PASSING THE FUNCTION AS PARAMETER
Util.changeBrightness = _changeBrightness;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Your app title',
theme: ThemeData(
primaryColor: const Color(0xFFb30047),
brightness: _brightness,
primarySwatch: Colors.blue,
accentColor: Colors.white,
/// ...and so on
在Util
类中
class Util {
static Brightness currentBrightness = Brightness.light;
static Function changeBrightness;
// ...further implementations
然后在需要时调用它。就我而言,设置屏幕中的开关发生了变化:
darkModeChanged(bool newValue) {
Preferences.setBool('darkMode', newValue);
setState(() {
_darkMode = newValue;
Util.currentBrightness = _darkMode ? Brightness.dark : Brightness.light;
Util.changeBrightness(Util.currentBrightness);
});
}
答案 2 :(得分:0)
您可以签出以下库:https://github.com/Norbert515/dynamic_theme
它允许您在运行时动态更改整个主题数据或应用程序的亮度。
答案 3 :(得分:0)
您可以在运行时使用ThemeBuilder更改主题:
setState(() {
ThemeBuilder.of(context).changeTheme();
});