Search code examples
flutterbloc

Flutter: The widget state does not change when using the BLOC architecture


I am studying the architecture of the block on Flutter. The simplest example:

  1. Page 1: on click red button, square set red color
  2. Click button Page 2 and open Page2
  3. Page 2: click green button
  4. Click on the back button and see that the square remains red

What am I doing wrong?

enter image description here

Code BLOC:

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

abstract class ColorEvent {}
class event_red extends ColorEvent {}
class event_green extends ColorEvent {}

class ColorBloc extends Bloc<ColorEvent, Color> {
  ColorBloc() : super(Colors.black) {
    on<event_red>((event, emit) {
      emit(Colors.red);
    });
    on<event_green>((event, emit)  {
      emit(Colors.green);
    }
    );
  }
  @override
  void onEvent(ColorEvent event) {
    super.onEvent(event);
    print(event);
  }
}

Code Page1:

void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Bloc',
      initialRoute: '/',
      routes: {
        "/": (BuildContext context) =>BlocProvider(create: (context) => ColorBloc(), child: MyHomePage(),),
        '/Page2':(BuildContext context) => BlocProvider(create: (context) => ColorBloc(), child: Page2(),),
      },
    );
  }
}
class MyHomePage extends StatefulWidget {
  _MyHomePageState createState() =>
      _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    ColorBloc _bloc = BlocProvider.of<ColorBloc>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Bloc'),
        centerTitle: true,
      ),
      body: Center(
        child: BlocBuilder<ColorBloc, Color>(
          builder: (context, currentColor) => Container(height: 100, width: 100, color: currentColor,
          ),
        ),
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            heroTag: "btn3",
            backgroundColor: Colors.red,
            onPressed: () {_bloc.add(event_red());},
          ),
          TextButton.icon(
              onPressed: () {
                Navigator.pushNamed(context, '/Page2');
              },
              icon: Icon(Icons.local_bar_sharp),
              label: Text("Page2")
          ),
        ],
      ),
    );
  }
}

Code Page2:

class Page2 extends StatefulWidget {
  _Page2State createState() =>
      _Page2State(); 
}
class _Page2State extends State<Page2> {
  final Page2_scaffoldKey = GlobalKey<ScaffoldState>();
  @override
  Widget build(BuildContext context) {
    var myBloc = BlocProvider.of<ColorBloc>(context);
    return
      Scaffold(
          key: Page2_scaffoldKey,
          appBar: AppBar(title: Text('Page2'),),
          body:
            FloatingActionButton(
              heroTag: "btn12",
              backgroundColor: Colors.green,
              onPressed: () {
                myBloc.add(event_green());
               // BlocProvider.of<ColorBloc>(context).add(event_green());
              },
            ),
      );
  }
}

Solution

  • Because you are using two ColorBloc instances for each page, try to use only one OrderBloc instance with like this:

    return BlocProvider<ColorBloc>(
      create: (context) => ColorBloc(),
      child:MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Bloc',
        initialRoute: '/',
        routes: {
          "/": (BuildContext context) =>MyHomePage(),
          '/Page2':(BuildContext context) =>  Page2(),
        },
      )
    );