如何监听 Flutter 中 platformBrightness 的变化?
How to listen for changes to platformBrightness in Flutter?
我正在设置一个系统,当用户将系统主题更改为深色模式时,它会更改主题并使用 Flutter,一切正常!但是,当用户更改系统主题时,系统导航和状态栏的颜色不会改变。我在构建方法内的主页上有代码 运行,但似乎没有这样做。这是主页构建方法中的代码:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Brightness sysBrightness = MediaQuery.of(context).platformBrightness;
if (sysBrightness == Brightness.dark)
Themes.setDarkSystemColors();
else
Themes.setLightSystemColors();
return Scaffold(
appBar: CustomAppBar(title: "Home"),
drawer: CustomDrawer(),
body: SizedBox(),
);
}
}
这是带有 theme:
和 darkTheme:
的主应用程序中的代码:
return MaterialApp(
initialRoute: '/',
routes: routes,
navigatorObservers: [_routeObserver],
theme: Themes.lightTheme,
darkTheme: Themes.darkTheme,
debugShowCheckedModeBanner: false,
title: 'School Life',
);
有一个 ThemeMode 枚举(我认为是从 Flutter 1.9 版开始)。因此,您可以将 theme
设置为浅色,将 darkTheme
设置为深色,然后 themeMode
(ThemeMode.system
(默认)、ThemeMode.light
、ThemeMode.dark
)确定哪个主题将被使用。
MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
)
但是,我不确定是否有办法侦听 platformBrightness 的变化(ThemeMode
也使用 platformBrightness 在后台)。您将需要重建 MaterialApp
...
使用(来自 WidgetsBinding)监听变化
void didChangePlatformBrightness()
https://api.flutter.dev/flutter/widgets/WidgetsBindingObserver/didChangePlatformBrightness.html
重写 initState
方法并使用 onPlatformBrightnessChanged
:
@override
void initState() {
super.initState();
final window = WidgetsBinding.instance.window;
// This callback is called every time the brightness changes.
window.onPlatformBrightnessChanged = () {
final brightness = window.platformBrightness;
};
}
要处理默认行为,请在上面的回调中添加以下行。感谢
WidgetsBinding.instance.handlePlatformBrightnessChanged();
完美运行,但它禁用了对小部件中平台亮度变化的自动反应,要解决此问题,请使用:
@override
void initState() {
super.initState();
var window = WidgetsBinding.instance!.window;
window.onPlatformBrightnessChanged = () {
WidgetsBinding.instance?.handlePlatformBrightnessChanged();
// This callback is called every time the brightness changes.
var brightness = window.platformBrightness;
};
}
另一种处理方式:
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
@override
void initState() {
WidgetsBinding.instance?.addObserver(this);
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}
@override
void didChangePlatformBrightness() {
var brightness = Theme.of(context).brightness;
super.didChangePlatformBrightness();
}
}
[2022 年 2 月] - 对我来说工作正常。
使用 - final Brightness brightness = MediaQuery.platformBrightnessOf(context);.
这将监听主题变化。您可以根据此更改进行不同的渲染。
@override
Widget build(BuildContext context) {
final Brightness brightness = MediaQuery.platformBrightnessOf(context);
bool isDarkMode = brightness == Brightness.dark;
稍后在 Widgets 渲染中基于 isDarkMode
例如:
AssetImage(isDarkMode ? darkBgImage : lightBgImage)
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(isDarkMode ? darkBgImage : lightBgImage),
fit: BoxFit.cover,
colorFilter:
const ColorFilter.mode(Colors.black45, BlendMode.darken),
),
),
),
我正在设置一个系统,当用户将系统主题更改为深色模式时,它会更改主题并使用 Flutter,一切正常!但是,当用户更改系统主题时,系统导航和状态栏的颜色不会改变。我在构建方法内的主页上有代码 运行,但似乎没有这样做。这是主页构建方法中的代码:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Brightness sysBrightness = MediaQuery.of(context).platformBrightness;
if (sysBrightness == Brightness.dark)
Themes.setDarkSystemColors();
else
Themes.setLightSystemColors();
return Scaffold(
appBar: CustomAppBar(title: "Home"),
drawer: CustomDrawer(),
body: SizedBox(),
);
}
}
这是带有 theme:
和 darkTheme:
的主应用程序中的代码:
return MaterialApp(
initialRoute: '/',
routes: routes,
navigatorObservers: [_routeObserver],
theme: Themes.lightTheme,
darkTheme: Themes.darkTheme,
debugShowCheckedModeBanner: false,
title: 'School Life',
);
有一个 ThemeMode 枚举(我认为是从 Flutter 1.9 版开始)。因此,您可以将 theme
设置为浅色,将 darkTheme
设置为深色,然后 themeMode
(ThemeMode.system
(默认)、ThemeMode.light
、ThemeMode.dark
)确定哪个主题将被使用。
MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
)
但是,我不确定是否有办法侦听 platformBrightness 的变化(ThemeMode
也使用 platformBrightness 在后台)。您将需要重建 MaterialApp
...
使用(来自 WidgetsBinding)监听变化
void didChangePlatformBrightness()
https://api.flutter.dev/flutter/widgets/WidgetsBindingObserver/didChangePlatformBrightness.html
重写 initState
方法并使用 onPlatformBrightnessChanged
:
@override
void initState() {
super.initState();
final window = WidgetsBinding.instance.window;
// This callback is called every time the brightness changes.
window.onPlatformBrightnessChanged = () {
final brightness = window.platformBrightness;
};
}
要处理默认行为,请在上面的回调中添加以下行。感谢
WidgetsBinding.instance.handlePlatformBrightnessChanged();
@override
void initState() {
super.initState();
var window = WidgetsBinding.instance!.window;
window.onPlatformBrightnessChanged = () {
WidgetsBinding.instance?.handlePlatformBrightnessChanged();
// This callback is called every time the brightness changes.
var brightness = window.platformBrightness;
};
}
另一种处理方式:
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
@override
void initState() {
WidgetsBinding.instance?.addObserver(this);
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}
@override
void didChangePlatformBrightness() {
var brightness = Theme.of(context).brightness;
super.didChangePlatformBrightness();
}
}
[2022 年 2 月] - 对我来说工作正常。
使用 - final Brightness brightness = MediaQuery.platformBrightnessOf(context);.
这将监听主题变化。您可以根据此更改进行不同的渲染。
@override
Widget build(BuildContext context) {
final Brightness brightness = MediaQuery.platformBrightnessOf(context);
bool isDarkMode = brightness == Brightness.dark;
稍后在 Widgets 渲染中基于 isDarkMode
例如:
AssetImage(isDarkMode ? darkBgImage : lightBgImage)
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(isDarkMode ? darkBgImage : lightBgImage),
fit: BoxFit.cover,
colorFilter:
const ColorFilter.mode(Colors.black45, BlendMode.darken),
),
),
),