在使用Bloc侦听器时,我会遇到一个错误ProvidNotFoundException(错误:找不到正确的提供商< todosbloc>

发布于 2025-02-06 12:14:32 字数 8447 浏览 3 评论 0原文

我正在学习集团,正在制作一个todo应用程序,但是在打电话给我的集团听众时,除了做屏幕之外,它还会出现错误。 错误在添加待办事项类别中显示

例外发生了。 providernotfoundException(错误:无法在此bloclistener< todosbloc,todosstate> widt部门上方找到正确的

提供商 您的选择。有几种常见的情况:

  • 您在main.dart中添加了一个新的提供商,并执行了热线功能。 要修复,请执行热点。

  • 您要阅读的提供商是在不同的路线中。

    提供商“范围”。因此,如果您将提供商插入路线中,则 其他路线将无法访问该提供商。

  • 您使用了buildContext,它是您要阅读的提供者的祖先。

确保bloclistener< todosbloc,todosstate>位于您的多个工业/提供商之下。 通常,当您创建提供商并试图立即阅读它时,这通常会发生。

  For example, instead of:

  ```
  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>().toString()),
    );
  }
  ```

  consider using `builder` like so:

  ```
  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, child) {
        // No longer throws
        return Text(context.watch<Example>().toString());
      }
    );
  }
  ```

If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter
)

这是我的代码...

main.dart

import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'home_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Color(0xff000A1F),
        appBarTheme: AppBarTheme(
          color: Color(0xff000A1F),
        ),
      ),
      home: MultiBlocProvider(providers: [
        BlocProvider(
          create: (context) => TodosBloc()
            ..add(
              LoadTodo(
                todos: [
                  Todo(
                    id: '1',
                    task: 'Sample Todo 1',
                    description: 'This is a test Todo',
                  ),
                  Todo(
                    id: '2',
                    task: 'Sample Todo 2',
                    description: 'This is a test Todo',
                  ),
                ],
              ),
            ),
        )
      ], child: HomeScreen()),
    );
  }
}

homescreen.dart

import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'add_todo_screen.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TodosBloc, TodosState>(
      builder: (context, state) {
        if (state is TodosLoading) {
          return CircularProgressIndicator();
        }
        if (state is TodosLoaded) {
          return Scaffold(
            appBar: AppBar(
              title: Text('Bloc Pattern To Dos'),
              actions: [
                IconButton(
                  onPressed: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => AddToDo(),
                      ),
                    );
                  },
                  icon: Icon(
                    Icons.add,
                    color: Colors.white,
                  ),
                ),
              ],
            ),
            body: Padding(
              padding: EdgeInsets.all(8.0),
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      child: Text(
                        'Pending To Dos..',
                        style: TextStyle(
                          fontSize: 18,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                    ListView.builder(
                        shrinkWrap: true,
                        itemCount: state.todos.length,
                        itemBuilder: (context, index) {
                          return _todoCard(state.todos[index]);
                        })
                  ]),
            ),
          );
        } else {
          return Text('Something Went Wrong');
        }
      },
    );
  }
}

Card _todoCard(Todo todo) {
  return Card(
    margin: EdgeInsets.only(bottom: 8.0, top: 8),
    child: Padding(
      padding: const EdgeInsets.all(10.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            '#${todo.id}: ${todo.task}',
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
            ),
          ),
          Row(
            children: [
              IconButton(
                onPressed: () {},
                icon: Icon(
                  Icons.add_task,
                ),
              ),
              IconButton(
                onPressed: () {},
                icon: Icon(
                  Icons.cancel,
                ),
              ),
            ],
          )
        ],
      ),
    ),
  );
}

添加到做屏幕。

import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class AddToDo extends StatelessWidget {
  TextEditingController controllerId = TextEditingController();
  TextEditingController controllerTask = TextEditingController();
  TextEditingController controllerDescription = TextEditingController();

  AddToDo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add to Dos'),
      ),
      body: BlocListener<TodosBloc, TodosState>(
        listener: (context, state) {
          if (state is TodosLoaded) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text("To Do Added Successfuly"),
              ),
            );
          }
        },
        child: Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Column(
              children: [
                _inputField('ID', controllerId),
                _inputField('Task', controllerTask),
                _inputField('Description', controllerDescription),
                Builder(builder: (context) {
                  return ElevatedButton(
                    onPressed: () {
                      var todo = Todo(
                        id: controllerId.text,
                        task: controllerTask.text,
                        description: controllerDescription.text,
                      );
                      context.read<TodosBloc>().add(AddTodo(todo: todo));
                    },
                    child: Text('Add Todo'),
                    style: ElevatedButton.styleFrom(
                      primary: Theme.of(context).primaryColor,
                    ),
                  );
                }),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

_inputField(String label, TextEditingController controller) {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text(
        '${label}:',
        style: TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.bold,
        ),
      ),
      Container(
        height: 50,
        margin: EdgeInsets.only(
          bottom: 10,
        ),
        width: double.infinity,
        child: TextFormField(
          controller: controller,
        ),
      )
    ],
  );
}

I am learning bloc and was making a todo app but while calling my bloc listener in addition to do screen it is throwing an error. Error is showing in Add To-Do Class

The exception has occurred.
ProviderNotFoundException (Error: Could not find the correct Provider above this BlocListener<TodosBloc, TodosState> Widget

This happens because you used a BuildContext that does not include the provider
of your choice. There are a few common scenarios:

  • You added a new provider in your main.dart and performed a hot-reload.
    To fix, perform a hot-restart.

  • The provider you are trying to read is in a different route.

    Providers are "scoped". So if you insert of provider inside a route, then
    other routes will not be able to access that provider.

  • You used a BuildContext that is an ancestor of the provider you are trying to read.

Make sure that BlocListener<TodosBloc, TodosState> is under your MultiProvider/Provider.
This usually happens when you are creating a provider and trying to read it immediately.

  For example, instead of:

  ```
  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>().toString()),
    );
  }
  ```

  consider using `builder` like so:

  ```
  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, child) {
        // No longer throws
        return Text(context.watch<Example>().toString());
      }
    );
  }
  ```

If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter
)

Here is my code...

Main.dart

import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'home_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Color(0xff000A1F),
        appBarTheme: AppBarTheme(
          color: Color(0xff000A1F),
        ),
      ),
      home: MultiBlocProvider(providers: [
        BlocProvider(
          create: (context) => TodosBloc()
            ..add(
              LoadTodo(
                todos: [
                  Todo(
                    id: '1',
                    task: 'Sample Todo 1',
                    description: 'This is a test Todo',
                  ),
                  Todo(
                    id: '2',
                    task: 'Sample Todo 2',
                    description: 'This is a test Todo',
                  ),
                ],
              ),
            ),
        )
      ], child: HomeScreen()),
    );
  }
}

HomeScreen.Dart

import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'add_todo_screen.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TodosBloc, TodosState>(
      builder: (context, state) {
        if (state is TodosLoading) {
          return CircularProgressIndicator();
        }
        if (state is TodosLoaded) {
          return Scaffold(
            appBar: AppBar(
              title: Text('Bloc Pattern To Dos'),
              actions: [
                IconButton(
                  onPressed: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => AddToDo(),
                      ),
                    );
                  },
                  icon: Icon(
                    Icons.add,
                    color: Colors.white,
                  ),
                ),
              ],
            ),
            body: Padding(
              padding: EdgeInsets.all(8.0),
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      child: Text(
                        'Pending To Dos..',
                        style: TextStyle(
                          fontSize: 18,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                    ListView.builder(
                        shrinkWrap: true,
                        itemCount: state.todos.length,
                        itemBuilder: (context, index) {
                          return _todoCard(state.todos[index]);
                        })
                  ]),
            ),
          );
        } else {
          return Text('Something Went Wrong');
        }
      },
    );
  }
}

Card _todoCard(Todo todo) {
  return Card(
    margin: EdgeInsets.only(bottom: 8.0, top: 8),
    child: Padding(
      padding: const EdgeInsets.all(10.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            '#${todo.id}: ${todo.task}',
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
            ),
          ),
          Row(
            children: [
              IconButton(
                onPressed: () {},
                icon: Icon(
                  Icons.add_task,
                ),
              ),
              IconButton(
                onPressed: () {},
                icon: Icon(
                  Icons.cancel,
                ),
              ),
            ],
          )
        ],
      ),
    ),
  );
}

Add To Do Screen.Dart

import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class AddToDo extends StatelessWidget {
  TextEditingController controllerId = TextEditingController();
  TextEditingController controllerTask = TextEditingController();
  TextEditingController controllerDescription = TextEditingController();

  AddToDo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add to Dos'),
      ),
      body: BlocListener<TodosBloc, TodosState>(
        listener: (context, state) {
          if (state is TodosLoaded) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text("To Do Added Successfuly"),
              ),
            );
          }
        },
        child: Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Column(
              children: [
                _inputField('ID', controllerId),
                _inputField('Task', controllerTask),
                _inputField('Description', controllerDescription),
                Builder(builder: (context) {
                  return ElevatedButton(
                    onPressed: () {
                      var todo = Todo(
                        id: controllerId.text,
                        task: controllerTask.text,
                        description: controllerDescription.text,
                      );
                      context.read<TodosBloc>().add(AddTodo(todo: todo));
                    },
                    child: Text('Add Todo'),
                    style: ElevatedButton.styleFrom(
                      primary: Theme.of(context).primaryColor,
                    ),
                  );
                }),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

_inputField(String label, TextEditingController controller) {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text(
        '${label}:',
        style: TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.bold,
        ),
      ),
      Container(
        height: 50,
        margin: EdgeInsets.only(
          bottom: 10,
        ),
        width: double.infinity,
        child: TextFormField(
          controller: controller,
        ),
      )
    ],
  );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥抱没勇气 2025-02-13 12:14:33

如果您打算在多个页面上使用集团,则必须将其放在材料App小部件上方,这是因为每个页面都是yeartialpage的孩子,请花一点时间阅读您的错误消息:

您要阅读的提供商是在不同的路线中。

提供商“范围”。因此,如果您将提供商插入路线中,那么其他路线将无法访问该提供商。

因此,而不是

MaterialApp(
  ...
  home: MultiBlocProvider(
    ...
  ),
  ...
);

这样做:

MultiBlocProvider(
  ...
  child: MaterialApp(
    ...
  ),
  ...
);

If you intend to use a bloc on multiple pages, you must put it above the MaterialApp widget, this is because every page is a child of the MaterialPage, please take a moment to read your error message:

The provider you are trying to read is in a different route.

Providers are "scoped". So if you insert of provider inside a route, then other routes will not be able to access that provider.

So instead of having

MaterialApp(
  ...
  home: MultiBlocProvider(
    ...
  ),
  ...
);

do this:

MultiBlocProvider(
  ...
  child: MaterialApp(
    ...
  ),
  ...
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文