【问题标题】:Error: Could not find the correct Provider<ThemeNotifier> above this Consumer<ThemeNotifier> Widget错误:在此 Consumer<ThemeNotifier> 小部件上方找不到正确的 Provider<ThemeNotifier>
【发布时间】:2020-11-15 18:17:46
【问题描述】:

我想在 Drawer 中使用带有 Switch 的 Dark/Light 主题。您可以在我的“drawerDosyasi.dart”中看到“Switch”。但首先我想在我的主页(Anasayfa)上用 SwitchListTile 编写代码。

两个问题:

1- 我现在遇到这个错误

错误:在此消费者小部件上方找不到正确的提供者

这可能是因为您使用了不包含提供程序的BuildContext 你的选择。有几种常见的情况:

  • 您尝试读取的提供程序位于不同的路径中。

    提供者是“范围的”。因此,如果您在路线内插入提供者,那么 其他路由将无法访问该提供程序。

  • 您使用了BuildContext,它是您尝试读取的提供程序的祖先。

    确保 Consumer 在您的 MultiProvider/Provider 下。 这通常发生在您创建提供程序并尝试立即读取它时。

    例如,而不是:

    Widget build(BuildContext context) {
      return Provider<Example>(
        create: (_) => Example(),
        // Will throw a ProviderNotFoundError, because `context` is associated
        // to the widget that is the parent of `Provider<Example>`
        child: Text(context.watch<Example>()),
      ),
    }
    

    考虑像这样使用builder

    Widget build(BuildContext context) {
      return Provider<Example>(
        create: (_) => Example(),
        // we use `builder` to obtain a new `BuildContext` that has access to the provider
        builder: (context) {
          // No longer throws
          return Text(context.watch<Example>()),
        }
      ),
    }
    

2- 我无法将开关移动到抽屉。给出关于转为 null 的错误。所以我希望能够在 DrawerHeader 中使用 Switch() 更改暗/亮模式

谁能修复我的代码?我是新手,两天解决不了问题。

anasayfa.dart

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => ThemeNotifier(),
      child: Consumer<ThemeNotifier>(
        builder: (context, ThemeNotifier notifier, child) {
          return MaterialApp(
            title: 'Flutter Theme Provider',
            theme: notifier.darkTheme ? dark : light,
            home: Anasayfa(),
          );
        },
      ),
    );
  }
}

class Anasayfa extends StatefulWidget {
  @override
  _AnasayfaState createState() => _AnasayfaState();
}

class _AnasayfaState extends State<Anasayfa> {
  int currentPage = 0;

  nested() {
    return NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return [
          SliverAppBar(
            toolbarHeight: 40,
            expandedHeight: 92.0,
            floating: false,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              background: Image.asset(
                "assets/images/besmele.jpg",
                fit: BoxFit.cover,
              ),
            ),
            actions: [
              IconButton(
                icon: Icon(Icons.account_circle),
                color: Colors.white,
                onPressed: () {},
              ),
            ],
          )
        ];
      },
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Consumer<ThemeNotifier>(
            builder: (context, notifier, child) => SwitchListTile(
              title: Text("Dark Mode"),
              onChanged: (val) {
                notifier.toggleTheme();
              },
              value: notifier.darkTheme,
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: nested(),
      drawer: Drawer(
        child: DrawerDosyasi(),
      ),
      bottomNavigationBar: CurvedNavigationBar(
        color: Colors.blue,
        backgroundColor: Colors.white,
        buttonBackgroundColor: Colors.blue,
        height: 50,
        items: <Widget>[
          Icon(
            Icons.campaign,
            size: 20,
            color: Colors.white,
          ),
          Icon(
            Icons.supervisor_account,
            size: 20,
            color: Colors.white,
          ),
          Icon(
            Icons.home,
            size: 20,
            color: Colors.white,
          ),
          Icon(
            Icons.video_collection_rounded,
            size: 20,
            color: Colors.white,
          ),
          Icon(
            Icons.menu_book_rounded,
            size: 20,
            color: Colors.white,
          ),
        ],
        animationDuration: Duration(
          milliseconds: 300,
        ),
        index: 2,
        animationCurve: Curves.bounceInOut,
        onTap: (index) {
          debugPrint("Current index is $index");
        },
      ),
    );
  }
}

drawerDosyasi.dart

    class DrawerDosyasi extends StatefulWidget {
  @override
  _DrawerDosyasiState createState() => _DrawerDosyasiState();
}

class _DrawerDosyasiState extends State<DrawerDosyasi> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: ListView(
        padding: EdgeInsets.zero,
        children: <Widget>[
          DrawerHeader(
            decoration: BoxDecoration(
              color: Colors.blue,
            ),
            child: Row(
              children: [
                Expanded(
                  flex: 1,
                  child: Switch(),
                ),
                Expanded(
                  flex: 3,
                  child: CircleAvatar(
                    radius: 60,
                    backgroundColor: Colors.white,
                  ),
                ),
                Expanded(flex: 1, child: SizedBox.expand()),
              ],
            ),
          ),
          ListTile(
            leading: Icon(Icons.home),
            title: Text('Anasayfa'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.account_circle),
            title: Text('Profil'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.campaign),
            title: Text('Duyurular'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.account_box),
            title: Text('Hocalar'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.library_books),
            title: Text('Dergiler'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.video_collection_rounded),
            title: Text('Canlı Dersler'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.menu_book_rounded),
            title: Text('Kütüphane'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.supervisor_account),
            title: Text('Tartışmalar'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.create),
            title: Text('Yazı Gönder'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.message_rounded),
            title: Text('İletişim'),
            tileColor: Colors.white,
          ),
          ListTile(
            leading: Icon(Icons.exit_to_app_rounded),
            title: Text('Çıkış'),
            tileColor: Colors.white,
          ),
        ],
      ),
    );
  }
}

theme.dart

ThemeData light = ThemeData(
    brightness: Brightness.light,
    primarySwatch: Colors.blue,
    accentColor: Colors.blue,
    scaffoldBackgroundColor: Color(0xfff1f1f1));

ThemeData dark = ThemeData(
  brightness: Brightness.dark,
  primarySwatch: Colors.indigo,
  accentColor: Colors.green[700],
);

class ThemeNotifier extends ChangeNotifier {
  final String key = "theme";
  SharedPreferences _prefs;
  bool _darkTheme;

  bool get darkTheme => _darkTheme;

  ThemeNotifier() {
    _darkTheme = true;
    _loadFromPrefs();
  }

  toggleTheme() {
    _darkTheme = !_darkTheme;
    _saveToPrefs();
    notifyListeners();
  }

  _initPrefs() async {
    if (_prefs == null) _prefs = await SharedPreferences.getInstance();
  }

  _loadFromPrefs() async {
    await _initPrefs();
    _darkTheme = _prefs.getBool(key) ?? true;
    notifyListeners();
  }

  _saveToPrefs() async {
    await _initPrefs();
    _prefs.setBool(key, _darkTheme);
  }
}

【问题讨论】:

    标签: android flutter dart switch-statement android-dark-theme


    【解决方案1】:
    1. Switch value 参数是必需的,onChanged 也是:

      Switch(value: false, onChanged: (value) {/* 用新值做某事*/})

    【讨论】:

      【解决方案2】:
      1. 你需要匹配Consumer&lt;T&gt;ChangeNotifierProvider&lt;T&gt;的类型参数
      Widget build(BuildContext context) {
          return ChangeNotifierProvider<ThemeNotifier>() 
      ...
      
      1. 您需要详细说明您的 Switch(),您究竟不想做什么。

      【讨论】:

      • 1.我认为类型应该从create方法中推断出来。
      • 我添加了 但给出了同样的错误。我希望能够在 DrawerHeader 处使用 Switch 更改暗/亮模式
      • @pirekare 也许发布一个堆栈跟踪。
      • @Patrick 我刚刚了解了堆栈跟踪是什么。我猜控制台上的错误消息,对吧?我在正文中添加错误消息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 2021-01-31
      • 2020-08-21
      • 2021-07-23
      • 2020-10-07
      • 1970-01-01
      相关资源
      最近更新 更多