SlideShare a Scribd company logo
1 of 25
Download to read offline
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

Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonfNataliya Patsovska
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법Jeado Ko
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every dayVadym Khondar
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"GeeksLab Odessa
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfKaty Slemon
 
React 101 by Anatoliy Sieryi
React 101 by Anatoliy Sieryi React 101 by Anatoliy Sieryi
React 101 by Anatoliy Sieryi Binary Studio
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeN Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeAnton Kulyk
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentanistar sung
 
This is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdfThis is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdfindiaartz
 
ASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CSASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CStutorialsruby
 
ASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CSASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CStutorialsruby
 
Scripting languages
Scripting languagesScripting languages
Scripting languagesteach4uin
 
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinWill your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinBarry Gervin
 
Week 8
Week 8Week 8
Week 8A VD
 

Similar to BLoC - Be Reactive in flutter (20)

mobl
moblmobl
mobl
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
 
GWT MVP Case Study
GWT MVP Case StudyGWT MVP Case Study
GWT MVP Case Study
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdf
 
React 101 by Anatoliy Sieryi
React 101 by Anatoliy Sieryi React 101 by Anatoliy Sieryi
React 101 by Anatoliy Sieryi
 
JavaScript Refactoring
JavaScript RefactoringJavaScript Refactoring
JavaScript Refactoring
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeN Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React Native
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
 
This is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdfThis is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdf
 
ASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CSASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CS
 
ASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CSASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CS
 
Scripting languages
Scripting languagesScripting languages
Scripting languages
 
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinWill your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
 
Android 3
Android 3Android 3
Android 3
 
Week 8
Week 8Week 8
Week 8
 
Web-First Design Patterns
Web-First Design PatternsWeb-First Design Patterns
Web-First Design Patterns
 

Recently uploaded

Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 

Recently uploaded (20)

Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 

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