Bloc 业务逻辑组件,其实就是把应用的一些逻辑单独拿出来放在一个类里面,我们可以利用这种架构创建反应式的应用。
Bloc 里面会用到Stream或者RxDart中的Observable。
class BlocDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CounterProvider(
bloc: CounterBloc(),
child: Scaffold(
appBar: AppBar(title: Text('BlocDemo'), elevation: 0.0,),
body: CounterHome(),
floatingActionButton: CounterActionButton(),
),
);
}
}
class CounterHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
CounterBloc _counterBloc = CounterProvider.of(context).bloc;
return Center(
child: StreamBuilder(
initialData: 0,
stream: _counterBloc.count,
builder: (context, snapshot) {
return ActionChip(
label: Text('${snapshot.data}'),
onPressed: () {
// _counterBloc.log();
_counterBloc.counter.add(1);
}
);
})
);
}
}
class CounterActionButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
CounterBloc _counterBloc = CounterProvider.of(context).bloc;
return FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
/* 点击按钮可以使用sink的add方法往stream上添加一个数据,Bloc会发送这个数据到指定的stream上,
显示数字的小部件可以使用streamBuilder生成,他会接收一个stream,当stream上的数据有变化的时候,
这个小部件就会被重建 */
// _counterBloc.log();
_counterBloc.counter.add(1);
},
);
}
}
// 使用 InheritedWidget 传递 Bloc
class CounterProvider extends InheritedWidget {
final Widget child;
final CounterBloc bloc;
CounterProvider({
this. child,
this.bloc,
}) : super(child : child);
static CounterProvider of(BuildContext context) =>
context.inheritFromWidgetOfExactType(CounterProvider);
@override
bool updateShouldNotify(InheritedWidget oldWidget) {
return true;
}
}
class CounterBloc {
int _count = 0;
final _counterActionController = StreamController<int>();
StreamSink<int> get counter => _counterActionController.sink;
final _counterController = StreamController<int>();
Stream<int> get count => _counterController.stream;
CounterBloc() {
_counterActionController.stream.listen(onData);
}
void onData(int data) {
print('$data');
_count = data + _count;
_counterController.add(_count);
}
void disponse() {
_counterActionController.close();
_counterController.close();
}
void log() {
print('Bloc');
}
}