如何监听 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 设置为深色,然后 themeModeThemeMode.system(默认)、ThemeMode.lightThemeMode.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),
                ),
              ),
            ),