Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use same bloc in multiple widgets

I'm facing issue in my current project so created this question im unable to get same bloc state in other widget i tried this https://github.com/felangel/bloc/issues/74#issuecomment-457968962 but i'm getting BlocProvider.of() called with a context that does not contain a Bloc of type CounterBloc. error if add Provider again in other widget another state is created for that page how to use same bloc state in different widgets.


import 'dart:async';

import 'package:flutter/material.dart';

import 'package:flutter_bloc/flutter_bloc.dart';

class SimpleBlocDelegate extends BlocDelegate {
  @override
  void onEvent(Bloc bloc, Object event) {
    print(event);
    super.onEvent(bloc, event);
  }

  @override
  void onTransition(Bloc bloc, Transition transition) {
    print(transition);
    super.onTransition(bloc, transition);
  }

  @override
  void onError(Bloc bloc, Object error, StackTrace stacktrace) {
    print(error);
    super.onError(bloc, error, stacktrace);
  }
}

void main() {
  BlocSupervisor.delegate = SimpleBlocDelegate();
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => ThemeBloc(),
      child: BlocBuilder<ThemeBloc, ThemeData>(
        builder: (_, theme) {
          return MaterialApp(
            title: 'Flutter Demo',
            home: BlocProvider(
              create: (_) => CounterBloc(),
              child: CounterPage(),
            ),
            theme: theme,
          );
        },
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter')),
      body: BlocBuilder<CounterBloc, int>(
        builder: (_, count) {
          return Column(
            children: <Widget>[
              Text(
                '$count',
                style: const TextStyle(fontSize: 24.0),
              ),
              RaisedButton(
                child: Text("Recreating state"),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => ThirdPage()),
                  );
                },
              ),
              RaisedButton(
                child: Text("Getting errorBlocProvider.of() called  "),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => FourthPage()),
                  );
                },
              )
            ],
          );
        },
      ),
      floatingActionButton: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              heroTag: "btn3",
              child: const Icon(Icons.add),
              onPressed: () =>
                  context.bloc<CounterBloc>().add(CounterEvent.increment),
            ),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              heroTag: "dd",
              child: const Icon(Icons.remove),
              onPressed: () =>
                  context.bloc<CounterBloc>().add(CounterEvent.decrement),
            ),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              heroTag: "btn2",
              child: const Icon(Icons.brightness_6),
              onPressed: () => context.bloc<ThemeBloc>().add(ThemeEvent.toggle),
            ),
          ),
        ],
      ),
    );
  }
}

**/// new state is created i want to use previous state**
///
///
class ThirdPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => CounterBloc(),
      child: BlocBuilder<CounterBloc, int>(
        builder: (BuildContext context, int count) {
          return Scaffold(
            backgroundColor: Colors.white,
            body: Center(child: Text('$count')),
          );
        },
      ),
    );
  }
}



**/// getting error BlocProvider.of() called with a context that does not co**
///
///
class FourthPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final CounterBloc _counterBloc = BlocProvider.of<CounterBloc>(context);
    return BlocBuilder<CounterBloc, int>(
      bloc: _counterBloc,
      builder: (BuildContext context, int count) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: Center(child: Text('$count')),
        );
      },
    );
  }
}

enum CounterEvent { increment, decrement }

class CounterBloc extends Bloc<CounterEvent, int> {
  @override
  int get initialState => 0;

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    switch (event) {
      case CounterEvent.decrement:
        yield state - 1;
        break;
      case CounterEvent.increment:
        yield state + 1;
        break;
      default:
        throw Exception('oops');
    }
  }
}

enum ThemeEvent { toggle }

class ThemeBloc extends Bloc<ThemeEvent, ThemeData> {
  @override
  ThemeData get initialState => ThemeData.light();

  @override
  Stream<ThemeData> mapEventToState(ThemeEvent event) async* {
    switch (event) {
      case ThemeEvent.toggle:
        yield state == ThemeData.dark() ? ThemeData.light() : ThemeData.dark();
        break;
    }
  }
}


like image 802
arjun more Avatar asked Apr 30 '20 16:04

arjun more


People also ask

How do you split widgets in Flutter?

Splitting An App: Use the Flutter Outline tool to split an app into widgets as shown below: Flutter Outline is present on the right-hand side as a hidden tab. After opening the tab we can see the Widget Tree of the current dart file. Right-click on the widget we want to extract -> click on Extract Widget.

How do I put widgets on top of another in Flutter?

In Flutter, the overlay lets you print visual elements on top of other widgets by inserting them into the overlay's stack. You insert a widget into the overlay using an OverlayEntry and you use Positioned and AnimatedPositioned to choose where the entry is positioned within the overlay.

What is BlocProvider in Flutter?

BlocProvider is a flutter widget that creates and provides a Bloc to all of its children. This is known as a dependency injection widget, so that a single instance of Bloc can be provided to multiple widgets within a subtree.


1 Answers

Use BlocProvider.value named constructor

class CounterPage extends StatefulWidget {
  @override
  _CounterPageState createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  CounterBloc counterBloc;

  @override
  void initState() {
    super.initState();
    counterBloc = BlocProvider.of<CounterBloc>(context);
  }

  @override
  void dispose() {
    counterBloc.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter')),
      body: BlocBuilder<CounterBloc, int>(
        builder: (_, count) {
          return Column(
            children: <Widget>[
              Text(
                '$count',
                style: const TextStyle(fontSize: 24.0),
              ),
              RaisedButton(
                child: Text("Recreating state"),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => BlocProvider<CounterBloc>.value(
                        value: counterBloc,
                        child: ThirdPage(),
                      ),
                    ),
                  );
                },
              ),
              RaisedButton(
                child: Text("Getting errorBlocProvider.of() called  "),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => BlocProvider<CounterBloc>.value(
                        value: counterBloc,
                        child: FourthPage(),
                      ),
                    ),
                  );
                },
              )
            ],
          );
        },
      ),
      // ....
    );
  }
}
like image 113
Federick Jonathan Avatar answered Nov 15 '22 11:11

Federick Jonathan