SlideShare a Scribd company logo
BLoC
Be Reactive in Flutter
Giacomo Ranieri
GDG Torino
@ilconteranieri
Il vostro Speaker
Giacomo Ranieri
Consulente
GDG Lead
Nerd
Ballerino
Sommario
La programmazione reattiva
Programmazione reattiva in flutter
BLoC come soluzione
Librerie di supporto
Conclusioni
La Programmazione
Reattiva
Cos’è ?
Orientata alla asincronicità
Stream di dati
Manipolazione tramite funzioni
x |
Valori Errore Fine
Stream
Un Esempio
1 1 1 1 1
Click Stream
1 2 3 4 5
Counter Stream
clickStream.map(f).scan(g)
map( click diventa 1 )
scan( somma )
La Programmazione
Reattiva in Flutter
Flutter è reattivo
Nato nel boom della programmazione reattiva
Ispirato a React
UI Reattiva
Partiamo dalla base
Widget con stato
Callback
class MyHomePage extends StatefulWidget {
...}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return ...
Text(
'$_counter',
),
...
Incrementer(_incrementCounter),
);
}
}
class Incrementer extends StatelessWidget {
final Function _incrementCounter;
const Incrementer(this._incrementCounter);
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
);
}
}
class MyHomePage extends StatefulWidget {
...}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return ...
Text(
'$_counter',
),
...
Incrementer(_incrementCounter),
);
}
}
class Incrementer extends StatelessWidget {
final Function _incrementCounter;
const Incrementer(this._incrementCounter);
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
);
}
}
Aggiungiamo un modello
Model
ScopedModel
ScopedModelDescendant<>
class MyHomePage extends StatefulWidget {
...}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return ScopedModel(
model: CounterModel(),
child: ...
ScopedModelDescendant<CounterModel>(
builder: (context, child, model) {
return Text(
model.counter.toString(),
);
},
),
...
Incrementer(),
);
}
}
class Incrementer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<CounterModel>(
builder: (context, child, model) {
return FloatingActionButton(
onPressed: () => model.increment(),
tooltip: 'Increment',
child: Icon(Icons.add),
);
},
);
}
}
class CounterModel extends Model {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter++;
notifyListeners();
}
}
class MyHomePage extends StatefulWidget {
...}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return ScopedModel(
model: CounterModel(),
child: ...
ScopedModelDescendant<CounterModel>(
builder: (context, child, model) {
return Text(
model.counter.toString(),
);
},
),
...
Incrementer(),
);
}
}
class Incrementer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<CounterModel>(
builder: (context, child, model) {
return FloatingActionButton(
onPressed: () => model.increment(),
tooltip: 'Increment',
child: Icon(Icons.add),
);
},
);
}
}
class CounterModel extends Model {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter++;
notifyListeners();
}
}
BLoC come
soluzione
E alla fine arriva BLoC
Stream
StreamBuilder
Business Logic
E alla fine arriva BLoC
class CounterBloc {
int _counter = 0;
Sink<int> get increment => _incrementController.sink;
final _incrementController = StreamController<int>();
Stream<String> get count => _countSubject.stream;
final _countSubject = BehaviorSubject<String>();
CounterBloc() {
_incrementController.stream.listen((event) {
_counter += event;
_countSubject.add('$_counter');
});
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider<CounterBloc>(
create: (context) => CounterBloc(),
child: MaterialApp(
...
home: MyHomePage(title: 'Counter'),
),
);
}
}
class MyHomePage extends StatefulWidget {
...}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final counterBloc = Provider.of<CounterBloc>(context);
return ...
StreamBuilder(
stream: counterBloc.count,
builder: (context, snapshot) {
return Text(
snapshot.data,
);
},
),
...
Incrementer(),
);
}
}
class Incrementer extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterBloc = Provider.of<CounterBloc>(context);
return FloatingActionButton(
onPressed: () => counterBloc.increment.add(1),
tooltip: 'Increment',
child: Icon(Icons.add),
);
}
}
Librerie di supporto
Per costruire i BLoC
Package bloc
Cubit
Bloc
Per sfruttare i BLoC
Package flutter_bloc
BlocProvider e MultiBlocProvider
BlocBuilder
Concludiamo
Bello ma non bellissimo
+ Forte separazione dei ruoli tra widget
+ Aggiornamenti puntuali della UI
+ Facilmente testabile
- Complesso da usare
Grazie!
Giacomo Ranieri
GDG Torino
@ilconteranieri

More Related Content

Similar to BLoC - Be Reactive in flutter (20)

PDF
mobl
zefhemel
 
PDF
Declarative presentations UIKonf
Nataliya Patsovska
 
PPT
GWT MVP Case Study
David Chandler
 
PDF
[FEConf Korea 2017]Angular 컴포넌트 대화법
Jeado Ko
 
PPT
Google Web Toolkit
Christos Stathis
 
PPTX
Reactive programming every day
Vadym Khondar
 
PDF
JSLab. Алексей Волков. "React на практике"
GeeksLab Odessa
 
PDF
Flutter State Management Using GetX.pdf
Katy Slemon
 
PPTX
React 101 by Anatoliy Sieryi
Binary Studio
 
PDF
JavaScript Refactoring
Krzysztof Szafranek
 
PDF
N Things You Don't Want to Repeat in React Native
Anton Kulyk
 
PDF
MOPCON 2014 - Best software architecture in app development
anistar sung
 
PDF
This is a C# project . I am expected to create as this image shows. .pdf
indiaartz
 
PDF
ASPNET_MVC_Tutorial_06_CS
tutorialsruby
 
PDF
ASPNET_MVC_Tutorial_06_CS
tutorialsruby
 
PPT
Scripting languages
teach4uin
 
PPTX
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
Barry Gervin
 
PPTX
Android 3
Robert Cooper
 
PPT
Week 8
A VD
 
PDF
Web-First Design Patterns
Michael Mahemoff
 
mobl
zefhemel
 
Declarative presentations UIKonf
Nataliya Patsovska
 
GWT MVP Case Study
David Chandler
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
Jeado Ko
 
Google Web Toolkit
Christos Stathis
 
Reactive programming every day
Vadym Khondar
 
JSLab. Алексей Волков. "React на практике"
GeeksLab Odessa
 
Flutter State Management Using GetX.pdf
Katy Slemon
 
React 101 by Anatoliy Sieryi
Binary Studio
 
JavaScript Refactoring
Krzysztof Szafranek
 
N Things You Don't Want to Repeat in React Native
Anton Kulyk
 
MOPCON 2014 - Best software architecture in app development
anistar sung
 
This is a C# project . I am expected to create as this image shows. .pdf
indiaartz
 
ASPNET_MVC_Tutorial_06_CS
tutorialsruby
 
ASPNET_MVC_Tutorial_06_CS
tutorialsruby
 
Scripting languages
teach4uin
 
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
Barry Gervin
 
Android 3
Robert Cooper
 
Week 8
A VD
 
Web-First Design Patterns
Michael Mahemoff
 

Recently uploaded (20)

PDF
Troubleshooting Virtual Threads in Java!
Tier1 app
 
PDF
Adobe Illustrator Crack Full Download (Latest Version 2025) Pre-Activated
imang66g
 
PDF
AI Image Enhancer: Revolutionizing Visual Quality”
docmasoom
 
PDF
Virtual Threads in Java: A New Dimension of Scalability and Performance
Tier1 app
 
PDF
Enhancing Security in VAST: Towards Static Vulnerability Scanning
ESUG
 
PDF
How to Download and Install ADT (ABAP Development Tools) for Eclipse IDE | SA...
SAP Vista, an A L T Z E N Company
 
PDF
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
PPTX
Role Of Python In Programing Language.pptx
jaykoshti048
 
PPTX
Employee salary prediction using Machine learning Project template.ppt
bhanuk27082004
 
PDF
AWS_Agentic_AI_in_Indian_BFSI_A_Strategic_Blueprint_for_Customer.pdf
siddharthnetsavvies
 
PDF
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PDF
Protecting the Digital World Cyber Securit
dnthakkar16
 
PDF
advancepresentationskillshdhdhhdhdhdhhfhf
jasmenrojas249
 
PPTX
TRAVEL APIs | WHITE LABEL TRAVEL API | TOP TRAVEL APIs
philipnathen82
 
PDF
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
PDF
Balancing Resource Capacity and Workloads with OnePlan – Avoid Overloading Te...
OnePlan Solutions
 
PDF
Enhancing Healthcare RPM Platforms with Contextual AI Integration
Cadabra Studio
 
PDF
How Agentic AI Networks are Revolutionizing Collaborative AI Ecosystems in 2025
ronakdubey419
 
PDF
Supabase Meetup: Build in a weekend, scale to millions
Carlo Gilmar Padilla Santana
 
PDF
Applitools Platform Pulse: What's New and What's Coming - July 2025
Applitools
 
Troubleshooting Virtual Threads in Java!
Tier1 app
 
Adobe Illustrator Crack Full Download (Latest Version 2025) Pre-Activated
imang66g
 
AI Image Enhancer: Revolutionizing Visual Quality”
docmasoom
 
Virtual Threads in Java: A New Dimension of Scalability and Performance
Tier1 app
 
Enhancing Security in VAST: Towards Static Vulnerability Scanning
ESUG
 
How to Download and Install ADT (ABAP Development Tools) for Eclipse IDE | SA...
SAP Vista, an A L T Z E N Company
 
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
Role Of Python In Programing Language.pptx
jaykoshti048
 
Employee salary prediction using Machine learning Project template.ppt
bhanuk27082004
 
AWS_Agentic_AI_in_Indian_BFSI_A_Strategic_Blueprint_for_Customer.pdf
siddharthnetsavvies
 
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
Protecting the Digital World Cyber Securit
dnthakkar16
 
advancepresentationskillshdhdhhdhdhdhhfhf
jasmenrojas249
 
TRAVEL APIs | WHITE LABEL TRAVEL API | TOP TRAVEL APIs
philipnathen82
 
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
Balancing Resource Capacity and Workloads with OnePlan – Avoid Overloading Te...
OnePlan Solutions
 
Enhancing Healthcare RPM Platforms with Contextual AI Integration
Cadabra Studio
 
How Agentic AI Networks are Revolutionizing Collaborative AI Ecosystems in 2025
ronakdubey419
 
Supabase Meetup: Build in a weekend, scale to millions
Carlo Gilmar Padilla Santana
 
Applitools Platform Pulse: What's New and What's Coming - July 2025
Applitools
 
Ad

BLoC - Be Reactive in flutter

  • 1. BLoC Be Reactive in Flutter Giacomo Ranieri GDG Torino @ilconteranieri
  • 2. Il vostro Speaker Giacomo Ranieri Consulente GDG Lead Nerd Ballerino
  • 3. Sommario La programmazione reattiva Programmazione reattiva in flutter BLoC come soluzione Librerie di supporto Conclusioni
  • 5. Cos’è ? Orientata alla asincronicità Stream di dati Manipolazione tramite funzioni x | Valori Errore Fine Stream
  • 6. Un Esempio 1 1 1 1 1 Click Stream 1 2 3 4 5 Counter Stream clickStream.map(f).scan(g) map( click diventa 1 ) scan( somma )
  • 8. Flutter è reattivo Nato nel boom della programmazione reattiva Ispirato a React UI Reattiva
  • 9. Partiamo dalla base Widget con stato Callback
  • 10. class MyHomePage extends StatefulWidget { ...} class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return ... Text( '$_counter', ), ... Incrementer(_incrementCounter), ); } } class Incrementer extends StatelessWidget { final Function _incrementCounter; const Incrementer(this._incrementCounter); @override Widget build(BuildContext context) { return FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ); } }
  • 11. class MyHomePage extends StatefulWidget { ...} class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return ... Text( '$_counter', ), ... Incrementer(_incrementCounter), ); } } class Incrementer extends StatelessWidget { final Function _incrementCounter; const Incrementer(this._incrementCounter); @override Widget build(BuildContext context) { return FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ); } }
  • 13. class MyHomePage extends StatefulWidget { ...} class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return ScopedModel( model: CounterModel(), child: ... ScopedModelDescendant<CounterModel>( builder: (context, child, model) { return Text( model.counter.toString(), ); }, ), ... Incrementer(), ); } } class Incrementer extends StatelessWidget { @override Widget build(BuildContext context) { return ScopedModelDescendant<CounterModel>( builder: (context, child, model) { return FloatingActionButton( onPressed: () => model.increment(), tooltip: 'Increment', child: Icon(Icons.add), ); }, ); } } class CounterModel extends Model { int _counter = 0; int get counter => _counter; void increment() { _counter++; notifyListeners(); } }
  • 14. class MyHomePage extends StatefulWidget { ...} class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return ScopedModel( model: CounterModel(), child: ... ScopedModelDescendant<CounterModel>( builder: (context, child, model) { return Text( model.counter.toString(), ); }, ), ... Incrementer(), ); } } class Incrementer extends StatelessWidget { @override Widget build(BuildContext context) { return ScopedModelDescendant<CounterModel>( builder: (context, child, model) { return FloatingActionButton( onPressed: () => model.increment(), tooltip: 'Increment', child: Icon(Icons.add), ); }, ); } } class CounterModel extends Model { int _counter = 0; int get counter => _counter; void increment() { _counter++; notifyListeners(); } }
  • 16. E alla fine arriva BLoC Stream StreamBuilder Business Logic
  • 17. E alla fine arriva BLoC
  • 18. class CounterBloc { int _counter = 0; Sink<int> get increment => _incrementController.sink; final _incrementController = StreamController<int>(); Stream<String> get count => _countSubject.stream; final _countSubject = BehaviorSubject<String>(); CounterBloc() { _incrementController.stream.listen((event) { _counter += event; _countSubject.add('$_counter'); }); } } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Provider<CounterBloc>( create: (context) => CounterBloc(), child: MaterialApp( ... home: MyHomePage(title: 'Counter'), ), ); } }
  • 19. class MyHomePage extends StatefulWidget { ...} class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { final counterBloc = Provider.of<CounterBloc>(context); return ... StreamBuilder( stream: counterBloc.count, builder: (context, snapshot) { return Text( snapshot.data, ); }, ), ... Incrementer(), ); } } class Incrementer extends StatelessWidget { @override Widget build(BuildContext context) { final counterBloc = Provider.of<CounterBloc>(context); return FloatingActionButton( onPressed: () => counterBloc.increment.add(1), tooltip: 'Increment', child: Icon(Icons.add), ); } }
  • 21. Per costruire i BLoC Package bloc Cubit Bloc
  • 22. Per sfruttare i BLoC Package flutter_bloc BlocProvider e MultiBlocProvider BlocBuilder
  • 24. Bello ma non bellissimo + Forte separazione dei ruoli tra widget + Aggiornamenti puntuali della UI + Facilmente testabile - Complesso da usare