I'm new to Flutter and I'm trying to use BLoC for state management. So I'm trying to rewrite flutter's default counter app using BLoC. Unfortunately my UI is not redrawn when the add button is pressed. I don't know what I'm doing wrong I'm using
bloc: ^6.1.0
equatable: ^1.2.5
flutter_bloc: ^6.0.6
Here is my code
counter_event.dart
part of 'counter_bloc.dart';
abstract class CounterEvent extends Equatable {
const CounterEvent();
@override
List<Object> get props => [];
}
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
counter_state.dart
part of 'counter_bloc.dart';
class CounterState extends Equatable {
final int counter;
const CounterState({@required this.counter});
@override
List<Object> get props => [counter];
}
counter_bloc.dart
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
part 'counter_event.dart';
part 'counter_state.dart';
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(counter: 0));
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
if (state is IncrementEvent) {
yield CounterState(counter: state.counter + 1);
} else if (state is DecrementEvent) {
yield CounterState(counter: state.counter - 1);
}
}
}
Here is the main function
main.dart
import 'package:counter_bloc/bloc/counter_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Home(title: 'Flutter Demo Home Page'),
);
}
}
class Home extends StatefulWidget {
Home({Key key, this.title}) : super(key: key);
final String title;
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
CounterBloc counterBloc = CounterBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: BlocBuilder<CounterBloc, CounterState>(
cubit: counterBloc,
builder: (context, state) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
state.counter.toString(),
style: Theme.of(context).textTheme.headline4,
),
],
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
counterBloc.add(IncrementEvent());
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
@override
void dispose() {
counterBloc.close();
super.dispose();
}
}
You can copy paste run full code below
Step 1: if (event is IncrementEvent) not state
Step 2: You need BlocProvider
home: BlocProvider<CounterBloc>(
create: (context) => CounterBloc(),
child: Home(
title: "test",
),
),
Step 3: You need to call BlocProvider.of<CounterBloc>
Widget build(BuildContext context) {
final CounterBloc counterBloc = BlocProvider.of<CounterBloc>(context);
working demo

full code
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
abstract class CounterEvent extends Equatable {
const CounterEvent();
@override
List<Object> get props => [];
}
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
class CounterState extends Equatable {
final int counter;
const CounterState({@required this.counter});
@override
List<Object> get props => [counter];
}
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(counter: 0));
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
print(event.toString());
if (event is IncrementEvent) {
print("inc");
yield CounterState(counter: state.counter + 1);
} else if (state is DecrementEvent) {
yield CounterState(counter: state.counter - 1);
}
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: BlocProvider<CounterBloc>(
create: (context) => CounterBloc(),
child: Home(
title: "test",
),
),
);
}
}
class Home extends StatefulWidget {
Home({Key key, this.title}) : super(key: key);
final String title;
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
final CounterBloc counterBloc = BlocProvider.of<CounterBloc>(context);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: BlocBuilder<CounterBloc, CounterState>(
//cubit: counterBloc,
builder: (context, state) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
state.counter.toString(),
style: Theme.of(context).textTheme.headline4,
),
],
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
print("click");
counterBloc.add(IncrementEvent());
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With