BLoC:
BLoC表示为业务逻辑组件 (Business Logic Component),而原理就是对StreamController的封装和延申出PublishSubject(普通广播的streamcontroll,可监听多次(默认异步)),BehaviorSubject(缓存最新一次事件的广播流控制器),ReplaySubject(缓存多个数据的广播流控制器,可以设定上限),做一个笔记,方便日后查看!
我们举一个例子说一下用法:
context.ancestorWidgetOfExactType(type);在flutter新版上方法已经过期。
过期方法:
static T of<T extends BlocBase>(BuildContext context) {
final type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
return provider.bloc;
新方法:
static T of<T extends BlocBase>(BuildContext context) {
BlocProvider<T> provider = context.findAncestorWidgetOfExactType<BlocProvider<T>>();
return provider.bloc;
}
构造BlocProvider
import 'package:flutter/material.dart';
abstract class BlocBase {
void dispose();
}
class BlocProvider<T extends BlocBase> extends StatefulWidget {
final T bloc;
final Widget child;
BlocProvider({
Key key,
@required this.child,
@required this.bloc,
}) : super(key: key);
@override
_BlocProviderState<T> createState() => new _BlocProviderState<T>();
static Type _typeOf<T>() => T;
static T of<T extends BlocBase>(BuildContext context) {
final type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
return provider.bloc;
}
}
class _BlocProviderState<T> extends State<BlocProvider<BlocBase>> {
@override
void dispose() {
widget.bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
创建登录LoginBlocBehaviorSubject 继承BlocProvider
class LoginBlocBehaviorSubject extends BlocBase {
// PublishSubject: 普通广播的streamcontroll,可监听多次(默认异步)
// BehaviorSubject: 缓存最新一次事件的广播流控制器
// ReplaySubject : 缓存多个数据的广播流控制器,可以设定上限
BehaviorSubject<Logn> _streamController = BehaviorSubject<Logn>();
StreamSink<Logn> get sink => _streamController.sink;
Stream<Logn> get stream => _streamController.stream;
@override
void dispose() {
_streamController.close();
}
/*
*登录
*/
void userLogin(int phone,String name) async{
//耗时操作:网络请求等待
Timer(Duration(seconds: 3),(){
return sink.add(Logn(phone,name));
});
}
}
界面中具体实现
跳转界面使用BlocProvider(child:null,bloc:null)把需要在child界面中使用的bloc传递进行使用,使用方法通过:LoginBlocBehaviorSubject loginBloc = BlocProvider.of(context);
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: "main",
routes: {
"main":(BuildContext ctx) =>BlocProvider(child: TestStreamControl(), bloc: LoginBlocBehaviorSubject()),
"zyjPage1":(BuildContext ctx) =>BlocProvider(child: zyjPage1(), bloc: LoginBloc()),
}
);
}
}
TestStreamControl 页面
class TestStreamControl extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return TestStreamControlState();
}
}
class TestStreamControlState extends State<TestStreamControl> {
@override
Widget build(BuildContext context) {
LoginBlocBehaviorSubject loginBloc = BlocProvider.of(context);
return Scaffold(
appBar: AppBar(
title: Text("StreamControl基础"),
),
body: Container(child: Column(
children: <Widget>[
StreamBuilder(
stream: loginBloc.stream,
builder: (BuildContext context, AsyncSnapshot<Logn> snapshot) {
return Container(
child: Column(
children: <Widget>[
Text("手机号:${snapshot?.data?.phone}"),
Text("姓名:${snapshot?.data?.name}")
],
),
);
}),
RaisedButton(onPressed: (){
loginBloc.userLogin(15832298162, "张三");
},child: Text("手机1"),),
],
),),
floatingActionButton: RaisedButton(
onPressed: () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_)=>BlocProvider(child: zyjPage1(), bloc: LoginBlocBehaviorSubject())));
},
child: Text("登录"),
),
);
}
}
zyjPage1页面
class zyjPage1 extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
LoginBlocBehaviorSubject loginBloc = BlocProvider.of(context);
return Scaffold(
appBar:AppBar(title: Text("界面1"),),
body:Container(child: Column(
children: <Widget>[
StreamBuilder(
stream: loginBloc.stream,
builder: (BuildContext context, AsyncSnapshot<Logn> snapshot) {
return Container(
child: Column(
children: <Widget>[
Text("手机号:${snapshot?.data?.phone}"),
Text("姓名:${snapshot?.data?.name}")
],
),
);
}),
RaisedButton(onPressed: (){
loginBloc.userLogin(12345677889, "zyj");
},child: Text("手机1"),),
RaisedButton(onPressed: (){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_)=>BlocProvider(child: TestStreamControl(), bloc: LoginBlocBehaviorSubject())));
},child: Text("返回"),),
],
),),
);
}
}
网友评论