Reputation: 1072
Recently I am start to learn Flutter and its BLoC partten, and there are many class in BLoC library, like Bloc
, PublishSubject
, StreamController
, BehaviorSubject
and etc..
My question is, what the scenarios that I can use these classes? For example, I can inherited from bloc
or not inherited from it, but why? I am confuse for that, What's the usage scenarios for those classes?
Upvotes: 1
Views: 1179
Reputation: 3326
As you can see, there are more than one ways to implement Bloc in your apps. The class you mentioned above are in fact from different packages: PublishSubject
and BehaviorSubject
are from rxdart package while StreamController
is within the Flutter SDK package dart:async
However, you are not required to use all or even any of them to implement Bloc in your Flutter apps. I'll make an example by implement Bloc without using any package:
1. Implement Bloc the vanilla way:
You can implement Bloc using what's in Flutter SDK without using other package. Usually you create a bloc class separating your logic from the UI. The class might look like this:
import 'dart:async';
// This is the class that handle all the logic such as receiving data from API, process those data, etc (I'll call it a data processing unit)
class YourBloc {
// Create a stream to send processed data to the UI
final StreamController _someController = StreamController();
Stream get someStream => _someController.stream;
// Get the data from API, then send the data to stream here. Usually an async function
void loadData() async {
final data = await doYourApiCall(); // Get data from API
var processedData = processYourData(data);
_someController.add(processedData);
}
dispose() {
_someController.close();
}
}
Meanwhile in the UI, you initiate the loadData() and listen to the response data with StreamBuilder
:
class _SomeScreenState extends State<SomeScreen> {
// Initiate your bloc
final YourBloc _bloc = YourBloc();
// Make the loadData() call
@override
void initState() {
_bloc.loadData();
super.initState();
}
@override
Widget build(BuildContext context) {
return StreamBuilder( // Listen to the datastream with StreamBuilder
stream: _bloc.someStream,
builder: (context, snapshot) {
if (!snapshot.hasData)
return Center(child: CircularProgressIndicator());
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) => _buildYourItem(index),
);
},
);
}
}
2. So what's the packages are for
There are some packages you can make use of to implement Bloc such as flutter_bloc or rxdart. flutter_bloc
provides a way to structure your bloc consistenly using Bloc/Event/State concepts, rx_dart
provides many tools so you can manipulate the Stream
to your own need. You might see people mentioned provider as well, it's main purpose is to pass an object down the widget tree and create a data flow through out your app.
Each is already pretty mature and implemented by many programmers. I recommend going into the documentations of each one of them only after you implement Bloc the vanilla way so you can actually understand what they're doing behind the scenes.
Upvotes: 3