颤振中的亮/暗模式

Posted

技术标签:

【中文标题】颤振中的亮/暗模式【英文标题】:Light / Dark Mode in flutter 【发布时间】:2021-09-08 08:40:14 【问题描述】:

我想将明暗模式开关放在应用程序中。开关没问题。但它在应用程序上没有任何变化。只是我看到了轻主题。 而且,当我单击开关时,我收到此错误或警告 (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;
  

注意:这段代码 sn-p 是关于 ThemeS 的项目的一部分。因为代码由很长的一行组成。

【问题讨论】:

***.com/questions/60232070/… 【参考方案1】:

在按钮上调用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 可以解决您的问题

【讨论】:

以上是关于颤振中的亮/暗模式的主要内容,如果未能解决你的问题,请参考以下文章

基于系统明暗模式的动态主题变化

将滤色器添加到图像的暗部分,将另一个滤色器添加到图像的亮部分?

多项活动中的暗模式

切换暗模式时,有啥方法可以更改 tailwindcss 中的图像?

如何在 swift UITests 中的 XCUIApplication 中设置暗模式?

markdown 禁用MacOS中的“暗模式”以进行单一应用