#flutter
#flutter
Вопрос:
Я новичок в Flutter, а также в использовании блоков.
У меня ошибка при компиляции кода:
The following assertion was thrown building Login(dirty, state: _LoginFormState#44e7f):
BlocProvider.of() called with a context that does not contain a Bloc of type BtnBloc.
No ancestor could be found starting from the context that was passed to
BlocProvider.of<BtnBloc>().
This can happen if the context you use comes from a widget above the BlocProvider.
This can also happen if you used BlocProviderTree and didn't explicity provide
the BlocProvider types: BlocProvider(bloc: BtnBloc()) instead of BlocProvider<BtnBloc>(bloc:
BtnBloc()).
The context used was: Login(dirty, state: _LoginFormState#44e7f)
Я пытался изменить некоторые вещи в моем классе bloc, но ничего не получается.
Вот мой класс blog :
class BtnBloc extends Bloc<BtnEvent, BtnState> {
@override
BtnState get initialState => BtnState.initial();
@override
Stream<BtnState> mapEventToState(
BtnState currentState, BtnEvent event) async* {
if (event is IdleEvent) {
yield currentState..state = 1;
} else if (event is LoadingEvent) {
yield currentState..state = 1;
} else if (event is RevealEvent) {
yield currentState..state = 2;
}
}
}
И вот мой метод сборки :
final _btnBloc = new BtnBloc();
_LoginFormState(
{Key key,
this.primaryColor,
this.backgroundColor,
this.backgroundImage,
this.logo});
@override
Widget build(BuildContext context) {
return BlocProvider(
bloc: _btnBloc,
child: BlocBuilder<BtnEvent, BtnState>(
bloc: BlocProvider.of<BtnBloc>(context),
builder: (context, BtnState state) {
return myWidget();
Пожалуйста, помогите мне:'(
Ответ №1:
Я надеюсь, что по прошествии некоторого времени, столкнувшись с этой проблемой, эта статья поможет вам лучше понять context
. Общее решение такое же, как ответ @Filled Stacks. Это означает, что вы должны передать блок при переходе на новую страницу, чтобы BlocProvider
можно было определить, какой тип блока вы получите.
Я рекомендую запустить функцию main для общего приложения, которая инициализирует ваши экраны и контекст через экраны. Например:
- Инициализация и блок передачи:
class ListTodoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider<TodoBloc>(
create: (context) => TodoBloc(TodoDao())..add(QueryTodoEvent()),
child: ListTodoPageful());
}
}
class ListTodoPageful extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return ListTodoState();
}
}
class ListTodoState extends State<ListTodoPageful> {
TodoBloc _todoBloc;
@override
Widget build(BuildContext context) {
_todoBloc = BlocProvider.of<TodoBloc>(
context);
//...
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => BlocProvider.value(
value: _todoBloc, child: CreateTaskPage())));
}
//...
}
- Блок приема:
class _CreatePageState extends State<CreateTaskPage> {
TodoBloc _todoBloc;
@override
Widget build(BuildContext context) {
_todoBloc = BlocProvider.of<TodoBloc>(context);
}
Обратитесь к моему образцу приложения здесь: https://github.com/huynguyennovem/flutter_todo
Ответ №2:
Строка ниже — ваша проблема. Ошибка — это именно то, о чем говорится в сообщении.
...
child: BlocBuilder<BtnEvent, BtnState>(
bloc: BlocProvider.of<BtnBloc>(context), <------- Problem line
builder: (context, BtnState state) {
...
К контексту, который вы там используете, не привязан Blockbuilder, поэтому ничто не передает блок сверху вниз в ваше loginState. Вы можете либо
- Используйте свой существующий блок (_btnBloc) и передайте его (рекомендуется)
- Оберните виджет, выводящий loginState на экран, с помощью BlocProvider, чтобы у вас был доступ к нему в состоянии виджета.
Если это ваш первый просмотр, тогда используйте 1.
Изменить
bloc: BlocProvider.of<BtnBloc>(context), <------- Problem line
Для
bloc: _btnBloc
Комментарии:
1. @VincentGuillois Рад, что помог.