美文网首页
flutter bloc基于ancestorWidgetOfEx

flutter bloc基于ancestorWidgetOfEx

作者: 翟小乙 | 来源:发表于2020-10-15 11:46 被阅读0次

#flutter bloc使用的三种方法#

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("返回"),),
         ],
       ),),
     );
  }

}

相关文章

网友评论

      本文标题:flutter bloc基于ancestorWidgetOfEx

      本文链接:https://www.haomeiwen.com/subject/flyfektx.html