简体   繁体   中英

Context does not contain bloc

in the following test code, I am trying to send an event to the TestBloc, when a button in the app bar is clicked. I moved the BlocBuilder outwards around the scaffold. But when the _reloadData method is called, then the following error pops up

 "BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type TestBloc"

Code

class _TestPageState extends State<TestPage> with UiPresenter {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => sl<TestBloc>()..add(GetDataEvent()),
      child: Scaffold(
        appBar: AppBar(
            title: AppBarTitleWidget(
          title: 'Test',
          onRefreshPressed: () => _reloadData(context),
        )),
        drawer: MainMenuDrawer(),
        body: ContentContainer(
          header: Text(
            'Test',
            style: Theme.of(context).textTheme.headline1,
          ),
          child: _buildBody(context),
    ),
      ),
    );
  }


_reloadData(BuildContext context) {
    BlocProvider.of<TestBloc>(context).add(GetDataEvent());
}

You can copy paste run full code below
I use the following full code to simulate this case
You can wrap AppBarTitleWidget with Builder
code snippet

    appBar: AppBar(title: Builder(builder: (BuildContext context) {
          return AppBarTitleWidget(
            title: "Test",
            onRefreshPressed: () => _reloadData(context),
          );
        }))

working demo

在此处输入图像描述

full code

import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class TestBloc extends Cubit<int> {
  /// {@macro counter_cubit}
  TestBloc() : super(0);

  /// Add 1 to the current state.
  void GetDataEvent() => emit(state + 1);

  /// Subtract 1 from the current state.
  void decrement() => emit(state - 1);
}

/*class CounterPage extends StatelessWidget {
  /// {@macro counter_page}
  const CounterPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => CounterCubit(),
      child: CounterView(),
    );
  }
}*/

/// {@template counter_observer}
/// [BlocObserver] for the counter application which
/// observes all [Cubit] state changes.
/// {@endtemplate}
class CounterObserver extends BlocObserver {
  @override
  void onChange(Cubit cubit, Change change) {
    print('${cubit.runtimeType} $change');
    super.onChange(cubit, change);
  }
}

void main() {
  Bloc.observer = CounterObserver();
  runApp(CounterApp());
}

class CounterApp extends MaterialApp {
  /// {@macro counter_app}
  CounterApp({Key key}) : super(key: key, home: TestPage());
}

_reloadData(BuildContext context) {
  BlocProvider.of<TestBloc>(context).GetDataEvent();
}

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  @override
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme;
    return BlocProvider(
      create: (_) => TestBloc(),
      child: Scaffold(
        appBar: AppBar(title: Builder(builder: (BuildContext context) {
          return AppBarTitleWidget(
            title: "Test",
            onRefreshPressed: () => _reloadData(context),
          );
        })),
        body: Center(
          child: BlocBuilder<TestBloc, int>(
            builder: (context, state) {
              return Text('$state', style: textTheme.headline2);
            },
          ),
        ),
        floatingActionButton: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: <Widget>[
            FloatingActionButton(
              key: const Key('counterView_increment_floatingActionButton'),
              child: const Icon(Icons.add),
              onPressed: () => context.read<TestBloc>().GetDataEvent(),
            ),
            const SizedBox(height: 8),
            FloatingActionButton(
              key: const Key('counterView_decrement_floatingActionButton'),
              child: const Icon(Icons.remove),
              onPressed: () => context.read<TestBloc>().decrement(),
            ),
          ],
        ),
      ),
    );
  }
}

class AppBarTitleWidget extends StatelessWidget {
  final String title;
  final VoidCallback onRefreshPressed;
  const AppBarTitleWidget({
    Key key,
    this.title,
    this.onRefreshPressed,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return InkWell(
        onTap: () {
          onRefreshPressed();
        },
        child: Text(title));
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM